設計模式--代理模式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();

}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM