动机
在面向对象系统中,有些对象由于某种原因,直接访问会给使用者、或者系统结构带来很多麻烦
某种原因是哪些呢?比如
- 对象创建的开销很大
- 某些操作需要安全控制
- 需要进程外的访问
- 比如在分布式系统中,你所用的对象是在另一个机器上创建的,你都不可能对它进行直接访问
如果在不失去透明操作对象的同时,来管理/控制这些对象特有的复杂性?增加一层间接层是软件开发中常用的解决方式
- 不失去透明操作:就是一致性,接口没有变,我可以像使用原对象一样使用代理层
- 管理/控制:代理层内部帮我们做一些复杂的操作,我们通过和原来一样的接口,就能完成管理/控制这些对象
模式定义
为其他对象提供一种代理以控制(隔离,隔离的方式就是使用接口)对这个对象的访问——《设计模式》GoF
结构

Subject是一个接口
- 把
Subject名字改成ISubject会好理解些
Client使用Subject时,真正创建和使用的应该是RealSubject这个对象
- 即
Subject* p = new RealSubject
但是由于某种特殊的原因
- 可能要对
RealSubject做性能优化 - 可能要在
RealSubject基础上做一些安全控制 - 可能
RealSubject是在另一个机器上,Client都不能直接使用RealSubject
这个时候
Client就应该去访问ProxyProxy去调用RealSubject,并扩展一些其他的内容(比如性能优化、安全控制)
示例
原始代码
//接口class ISubject{public:virtual void process();};//实现ISubjectclass RealSubject: public ISubject{public:virtual void process(){//业务逻辑处理//...}};//客户端程序class ClientApp{ISubject* subject;public:ClientApp(){//创建RealSubject//这里可以使用工厂,或者其他方式,反正就是绕来绕去创建到一个RealSubjectsubject=new RealSubject();}void DoTask(){//...subject->process();//....}};
这样写,可能遇到以下情况
RealSubject在别的进程(甚至另一个计算机)中,你无法直接访问- 要在
RealSubject基础上做一些性能优化、安全控制等等
优化:代理模式
增加一个代理层Proxy,客户端程序使用Proxy,而不使用RealSubject
//接口class ISubject{public:virtual void process();};//Proxy,一个代理层class SubjectProxy: public ISubject{public:virtual void process(){//对RealSubject的一种间接访问//1. 如果RealSubject在另一个进程或别的计算机中,需要通过网络层实现调用//2. 其他一些事情,如性能优化、安全控制//....}};//客户端class ClientApp{ISubject* subject;public:ClientApp(){//使用Proxy,而不直接使用RealSubjectsubject=new SubjectProxy();}void DoTask(){//...subject->process();//....}};
要点总结
“增加一层间接层”是软件系统中对许多复杂问题的一种常见解决方法。在面向对象系统中,直接使用某些对象会带来很多问题,作为间接层的proxy对象便是解决这一问题的常用手段。
具体Proxy设计模式的实现方法、实现粒度都相差很大,有些可能对单个对象做细粒度的控制,如copy-on-write技术,有些可能对组件模式提供抽象代理层,在架构层次对对象做proxy。
Proxy并不一定要求保持接口完整的一致性,只要能够实现间接控制,有时损失一些透明性是可以接受的。
在实际开发中,有一些工具能够帮我们实现代理类
- C++使用REST架构时,有一些工具能够帮我们生成REST接口的代理类(这些代理类往往不是手工写的,手工写非常复杂,你要控制所有网络访问的细节),生成之后,在C++层面使用代理类是非常方便的
