背景
在某些情况下,一个客户不想或者不能直接引用一个对象,此时可以通过一个称之为“代理”的第三者来实现间接引用。代理对象可以在客户端和目标对象之间起到中介的作用,并且可以通过代理对象去掉客户不能看到的内容和服务或者添加客户需要的额外服务。
通过引入一个新的对象来实现对真实对象的操作或者将新的对象作为真实对象的一个替身,这种实现机制即为代理模式,通过引入代理对象来间接访问一个对象,这就是代理模式的动机。
概述
代理模式(Proxy Pattern) :给某一个对象提供一个代理,并由代理对象控制对原对象的引用。代理模式的英文叫做Proxy或Surrogate,它是一种对象结构型模式。
模式结构
代理模式包含如下角色:
Subject: 抽象主题角色
抽象主题角色声明了真实主题和代理主题的共同接口,实现了调用方和服务方的解耦。
Proxy: 代理主题角色
代理主题角色内部包含对真实主题的引用,从而可以在任何时候操作真实主题对象。
RealSubject: 真实主题角色
真实主题角色定义了代理角色所代表的真实对象,在真实主题角色中实现了真实的业务操作,客户端可以通过代理主题角色间接调用真实主题角色中定义的方法。
代码实现
//抽象系统类
class AbstractCommonInterface{
public:
virtual void run() = 0;
};
class MyFunc :public AbstractCommonInterface{
public:
virtual void run(){
cout << "run..." << endl;
}
};
class MrFuncProxy:public AbstractCommonInterface{
public:
MyFunc*pFunc;
string mUserInfo;
public:
MrSystemProxy(string userInfo){
this->mUserInfo = userInfo;
pFunc = new MyFunc;
}
~MyFuncProxy(){
if (NULL != pFunc) {
delete pFunc;
}
}
virtual void run(){
if (checkUserInfo()){
cout << "user info is right." << endl;
this->pFunc->run();
}
else{
cout << "error." << endl;
}
}
};
void ProxyFunc() {
MyFuncProxy* proxy = new MyFuncProxy("root,123");
proxy->run();
delete proxy;
proxy = new MyFuncProxy("admin,123");
proxy->run();
delete proxy;
}
特点
优点
代理模式能够协调调用者和被调用者,在一定程度上降低了系统的耦合度。
虚拟代理通过使用一个小对象来代表一个大对象,可以减少系统资源的消耗,对系统进行优化并提高运行速度。
保护代理可以控制对真实对象的使用权限。
缺点
额外增加了代理层,可能造成请求的请求响应变慢。
需要额外增加代理层的实现逻辑,可能会比较复杂。
应用场景
图片代理
在Web中浏览大图一般使用图片代理实现,即用户访问某大图时不时直接加载该图片,这样会很消耗网络带宽,而是采用先向客户端浏览器加载一个小图,然后在后台加载大图,这样可以大幅度提升用户体验。
远程代理
远程代理可以将网络的细节隐藏起来,使得客户端不必考虑网络的存在。
虚拟代理
虚拟代理模式是一种内存节省技术,那些占用大量内存或处理复杂的对象将推迟到使用它的时候才创建。