代理(Proxy)模式和状态(State)模式都提供一个代理(Surrogate)类。代码与代理类打交道,而做实际工作的类隐藏在代理类背后。当调用代理类中的一个函数时,代理类仅转而去调用实现类中相应的函数,
代理模式和状态模式的区别很简单:代理模式只有一个实现类,而状态模式可以有多个实现。代理模式和状态模式的应用也不相同:代理模式控制其对实现类的访问,而状态模式动态地改变其实现类。
#include <iostream> using namespace std; class ProxyBase { public: virtual void f() = 0; virtual void g() = 0; virtual void h() = 0; virtual ~ProxyBase() {} }; class Implementation : public ProxyBase { public: void f() { cout << "Implementation.f()" << endl; } void g() { cout << "Implementation.g()" << endl; } void h() { cout << "Implementation.h()" << endl; } }; class Proxy : public ProxyBase { ProxyBase* implementation; public: Proxy() { implementation = new Implementation(); } ~Proxy() { delete implementation; } // Forward calls to the implementation: void f() { implementation->f(); } void g() { implementation->g(); } void h() { implementation->h(); } }; int main() { Proxy p; p.f(); p.g(); p.h(); }
代理模式与状态模式之间的不同之处在于它们所解决的问题不同。GoF中给出了代理模式的一般用途,描述如下:
- 远程代理(Remote Proxy)。为不同地址空间的对象提供代理。通赤某些远程对象技术实现。
- 虚拟代理(Virtual Proxy)。根据需要提供一种“惰性初始化”方式来创建高代价的对象。
- 保护代理(Protection proxy)。当不愿意客户程序员拥有被代理对象的全部仿问权限时,使用保护代理。
- 巧妙引用(Smart reference)。当访问被代理对象时,增加额外的活动。引用计数(reference counting)就是一个例子:它用来跟踪被代理的某个特定对象被引用的次数。一个更简单的例子就是对特定函数的调用进行计数。
选自《C++编程思想》。