zoukankan      html  css  js  c++  java
  • 设计模式--代理模式C++实现

    代理模式C++实现

    1定义

    为其他对象提供一种代理以控制对这个对象的访问

    2类图

    角色定义:

    Subject抽象主体角色,抽象类或者接口,是一个普通的业务类型定义

    RealSubject具体主体角色,也叫作被委托角色,被代理角色。业务逻辑的具体执行者

    Proxy代理主体角色,委托类,代理类。

    3实现

    class Subject

    {

    public:

      virtual ~Subject()=0;

      virtual void Request()=0;//具体代理的任务

    protected:

      Subject();

    };

    class ConcreteSubject:public Subject

    {

    public:

      ConcreteSubject();

      ~ConcreteSubject();

      void Request();

    };

    class Proxy:public Subject

    {

    public:

      Proxy();

      Proxy(Subject* _sub);

      void Request()//实现对委托者的委托任务执行与补偿

      {

        bef();

        this->_sub->Request();

        end();

      }

      void bef()

      {}

      void end()

      {}

      ~Proxy();

    private:

      Subject* _sub;

    };

    注:由此可看出,代理模式最大的好处便是逻辑与实现的彻底解耦

    3应用

    ①优点

    职责清晰(实现好内部结构就可以,具体客户要求由代理进行分化)

    高扩展性(具体主题角色随时变化,只要他实现了接口,无论如何都逃不出代理的手掌,所以代理无论如何都是可以使用的)

    智能化()

    ②使用场景

    eg打官司找律师,游戏代练。。。目的就是为了减轻自己的负担。具体参见Spring AOP,这是个典型的代理模式

    4扩展

    ①普通代理

    用户设置代理ip地址,确保用户知道代理的存在。调用者只需要知道代理存在就好,而不用知道代理了谁。对真实角色的构造,调用进行项目组约定

    ②强制代理

    调用者直接调用真实角色,而不关心代理是否存在,其代理的产生有真实角色决定。

    ——强制要求,你必须通过真实角色查找到代理角色,否则不能访问

    实现方案:

    在真实角色中定义自己的代理者。每个流程的执行都首先判断是否有代理存在,否则提示无法访问

    在代理角色中,代理的代理返回this;

    5 代理的升级

    ①过滤,拦截等功能。

    eg游戏代理增加计费功能。

    需要增加接口Iproxy,实现功能的增加

    6动态代理

    定义:

    实现阶段不用关心代理谁,而在运行阶段指定代理哪一个对象。AOP(Aspect Oriented Programming)面向横切面编程。核心就是动态代理。

    其实其核心就是这个动态问题的解决了,利用C++中的多态,回调等方案,我们就可以实现。

    类图

    实现

    动态代理类

    class GamePlayH:public InvocationHandler

    {

    public:

      GamePlayH(object _obj)

      {

        this->obj = _obj;

      }

      //核心方法,通过接收被代理实例,其方法,参数。对其进行代理调用

      //相关问题由客户端传入

      object invoke(object proxy,Method method,object[]args)

      {

        object result = method.invoke(this.obj,args);

        return result;

      }

    private:

      object _obj; //被代理的实例

    };

    改进:增加一个具体检测功能

     object invoke(object proxy,Method method,object[]args)

      {

        object result = method.invoke(this.obj,args);

        if(obj.当前状态)

        {cout << " 状态错误..."<<endl;}

        return result;

      }

     AOP编程,面向横切面编程。

    没有使用新技术,但是对于我们的设计,编码都有非常大的影响,对日志,事物,权限等问题,在系统设计时都不用考虑,而在设计后通过AOP方式切过去。

     

    解释:两条独立发展的路线。动态代理实现代理的职责,业务逻辑Subject实现相关的逻辑功能,两者之间没有必然的相互耦合的关系。通知从另一个切面切入,最终在高层模块也就是Client耦合,完成逻辑的封装任务。

    实现

    class Subject

    {

    public:

      virtual void DoSomething(string str) = 0;

    };

    //真实主题

    class RealSubject :public Subject

    {

      void DoSomething(string str)

      {

        cout << "Do Something" << str << endl;

      }

    };

    //动态代理的Handler类

    class MyInvocationHandler :public InvocationHandler

    {

    private:

      object target = NULL;

    public:

      MyInvocationHandler(object _obj)

      {

        target  = _obj;

      }

      //代理方法

      object invoke(object proxy,Method method,object[]args)

      {

        return method.invoke(target,args);

      }

    };

    //动态代理类......关键

    template<class T>

    class DynamicProxy

    {

    public:

      static T newProxyInstance(ClassLoader loader, Class Instance,InvocationHandler h)

      {

        //找到JoinPoint连接点,AOP框架使用元数据定义

        if(true)

        {

          //执行一个前置通知

          (new BeforeAdvice()).exec();  

        }

        return (T)Proxy.newProxyInstance(loader,interface,h);

      }

    };

    注:类中插入了AOP术语,eg 在什么连接点执行什么操作。这是一个简单的横切面编程。

    class IAdvice

    {

    public:

      void exec();

    }

    class BeforeAdvice:public IAdvice

    {

    public:

      void exec()

      {

        cout << "this is BeforeAdvice,I am Running"<<endl;

      }

    };

    //场景类

    class Client

    {

    public:

      //主题定义

      Subject sub = new RealSubject();

      //Handler定义

      InvocationHandler handler = new MyInvocationHandler(sub);

      //定义主题的代理

      Subject proxy= DynamicProxyInstance(subject.getClass().getClassLoader(), subject.getClass().getInterfaces(),handler);

      //代理的行为

      proxy.DoSomething();

    }

  • 相关阅读:
    《我是一只IT小小鸟》
    实现对字符串的反转输出与句子的反转输出
    7.13学习记录
    CentOS 7 不能连接网路的解决方法
    Xshell连接linux服务器不成功的乌龙问题
    Python基础(二)数据类型
    Python基础(一)
    UML精粹3
    UML精粹2
    UML精粹1
  • 原文地址:https://www.cnblogs.com/lang5230/p/5322668.html
Copyright © 2011-2022 走看看