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