代理模式:在代理对象中给某个对象提供一个代理或者占位符,由代理对象控制对对象的访问。
使用代理模式的原因有多种,这里我们分开讲一下!
1.远程代理:本地客户端代理远程服务器,可以通过本地客户端对象去控制远程服务器去做一些操作。
对于这个我的理解就是:像是QQ提供的远程服务就是这个原理,通过代理协议去绑定对方电脑,我们的电脑就是代理对象。我们可以远程控制对方电脑去做一些操作。
2.虚拟代理:创建开销很大的对象时,通过代理存放实例化需要很长时间的真实对象。 比较常见的情况是:我们平时打开一个网页,里面的图片还没加载出来,此时,网页的表格,图片框等布局已经处理好了。原因是文字,图片等数据是需要慢慢下载的,代理存储了真实的图片路劲和尺寸。下载之前,虚拟代理用未打开的图片框替代真实的图片去创建网页对象。
3.安全代理:用来控制对真实对象访问操作的权限。
4.智能指引:在调用真实对象时,代理还会出来其他事情。比如计算真实对象的引用计数。
举个栗子吧!我们想要翻墙去访问国外的网站(被代理对象)时,需要什么呢?没错,就是VPN(代理)
这里,我们正常访问国内网站是不需要VPN(代理)的,因此,相关类图可以是这样子的:
先看看类图:
直接看代码吧:
class Web
{
public:
Web(string name)
{
mName = name;
};
virtual bool IsForeign() = 0;
void processRequest()
{
cout << "你正在访问 "<< mName << endl;
};
private:
string mName;
};
class ForeignWeb:public Web
{
public:
ForeignWeb(string name)
:Web(name)
{
}
bool IsForeign()
{
return true;
};
};
class InlandWeb :public Web
{
public:
InlandWeb(string name)
:Web(name)
{
}
bool IsForeign()
{
return false;
};
};
class Client
{
virtual void VisitWeb(Web& web) = 0;
};
class VPN :public Client
{
public:
void VisitWeb(Web& web)
{
web.processRequest();
}
};
class InlandClient:public Client
{
public:
void VisitWeb(Web& web)
{
if (web.IsForeign())
{
VPN* vpn = new VPN;
cout << "通过VPN访问:" << endl;
vpn->VisitWeb(web);
}
else
{
web.processRequest();
}
}
};
int main()
{
ForeignWeb* youtobe = new ForeignWeb("YouTobe");
InlandWeb* bilibili = new InlandWeb("Bilibili");
InlandClient* inlandclient = new InlandClient();
inlandclient->VisitWeb(*youtobe);//访问外国网站需要VPN
cout << endl;
inlandclient->VisitWeb(*bilibili);//访问国内不需要
}
在上面的代码中,国内网站是不需要VPN(代理)的,但是国外网站是需要的。所以访问Youtobe的时候时通过VPN代理去访问ForeignWeb的。
代理模式优缺点是什么呢?什么时候应该使用代理模式呢?
优点:
可动态代理多个实现同一个接口的类。
在客户端和目的对象之间起保护目标对象的作用。
降低耦合度,增加程序可拓展性。
编程简洁:目标对象不用关心其他非本职工作,可通过后期的代理完成所有事务。
缺点:
目标和客户端之间增加了代理对象,处理速度变慢。
那我们什么时候使用代理模式呢?
我整理了几种情况:
不想把自己暴露给别人时。
客观条件上客户端无法直接调用对象,需要中转完成。
对象创建消耗大,需要缓冲加载。
需要通过代理对访问被代理对象进行访问限制时。