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