代理模式的目的是为其他对象提供一种代理以控制对这个对象的访问。我们接触到的迭代器也可以理解为一种代理,我们通过它来间接对容器中元素进行访问。
代理模式中,有以下几个参与角色:
- RealSubject 表示用户真正要访问的对象;
- Proxy 表示代理对象,即:我们不允许用户直接访问 RealSubject,而是希望用户通过 Proxy 对象间接访问 RealSubject 对象;
- Subject 对象用于定义 RealSubject 和 Proxy 的公共部分的接口。假设:我们想要用户访问 RealSubject 的 do 函数,我们也会在 Proxy 内部增加一个同样的 do 函数,这样用户虽然是通过 Proxy 访问的 RealSubject 对象,但是访问的接口是相同的。
下面是一个简单的示例代码:
#include <iostream> using namespace std; class Subject { public: virtual void request() = 0; }; class RealSubject : public Subject { public: virtual void request() { cout << "RealSubject request" << endl; } }; class RealSubjectProxy : public Subject { public: RealSubjectProxy(RealSubject *real_subject): p_real_subject(real_subject) {} virtual void request() { // 通过代理类间接访问 RealSubject 的 request 函数 p_real_subject->request(); } ~RealSubjectProxy() { if (p_real_subject != nullptr) { delete p_real_subject; } } private: RealSubject* p_real_subject{nullptr}; }; void client() { // 使用的时候,将真实被访问的对象交给代理类来管理 RealSubjectProxy proxy(new RealSubject); // 通过代理类来实现间接访问真实对象 proxy.request(); } int main() { client(); return 0; }
我们可以直接去访问 RealSubject 对象,当然我们也可以新增一个代理类,当需要访问 RealSubject 对象时,就用过代理类间接来访问。这么设计代码是看起来复杂多了,似乎代码量也多了起来。但是代码扩展就会比较容易一些。比如:要给该类对象的访问增加一些访问权限,就可以新增一个代理类来完成,而不需要修改原来的 RealSubject 代码。
代理模式这种代码设计方式在很多场景应用都很广泛,重点是理解其思想。简单来讲,就是原来我们直接可以干的事情,现在不直接干。间接的访问方式,能够给我们充足的空间去干预中间过程。这样既可以方便复用代码(不需要为不同的需求去写一遍相同的 RealSubject 代码),也方便扩展代码(需要对如何对 RealSubject 进行何种访问控制,只需要新增一个对应的代理类即可)。