1、描述
代理是一种结构型设计模式,让你能提供真实服务对象的替代品给客户端使用。代理接收客户端的请求并进行一些处理(访问控制和缓存等),然后再将请求传递给服务对象。
代理对象拥有和服务对象相同的接口,这使得当其被传递给客户端时可与真实对象互换。
优点:职责清晰;高扩展性;智能化;
2、结构图
- Subject声明了服务接口,代理必须遵循该接口才能伪装成服务对象
- RealSubject提供了一些实用的业务逻辑
- Proxy包含了一个指向RealSubject对象的引用成员变量。代理完成其任务(例如延迟初始化、记录日志、访问控制和缓存等)后会将请求传递给RealSubject。
- Client能通过统一接口与RealSubject或者Proxy交互。
3、C++代码
#include <iostream>
//声明了RealSubject和Proxy共同的接口。只要客户端只使用RealSubject的该接口,那么就可以
//使用Proxy替换RealSubject
class Subject {
public:
virtual void Request() const = 0;
};
//RealSubject类包含了核心业务逻辑。RealSubject可能是比较慢和低效的,Proxy类
//可以在不修改代码的情况下解决这些问题
class RealSubject : public Subject {
public:
void Request() const override {
std::cout << "RealSubject: Handling request.\n";
}
};
//Proxy类具有和RealSubject相同的接口
class Proxy : public Subject {
private:
RealSubject *real_subject_;
bool CheckAccess() const {
// 可以在这执行一些检查工作
std::cout << "Proxy: Checking access prior to firing a real request.\n";
return true;
}
void LogAccess() const {
std::cout << "Proxy: Logging the time of request.\n";
}
//Proxy维护对RealSubject类对象的引用。它可以是延迟加载的,也可以由客户端传递给Proxy。
public:
Proxy(RealSubject *real_subject) : real_subject_(new RealSubject(*real_subject)) {
}
~Proxy() {
delete real_subject_;
}
//最常用的Proxy是延迟加载、缓存、访问控制、日志记录等。
void Request() const override {
if (this->CheckAccess()) {
this->real_subject_->Request();
this->LogAccess();
}
}
};
//客户代码使用Subject声明的公共接口,这样不管是RealSubject还是Proxy都是通用的。
//实际中,客户可能直接使用RealSubject,在这种情况下,可以直接让代理继承RealSubject。
void ClientCode(const Subject &subject) {
// ...
subject.Request();
// ...
}
int main() {
std::cout << "Client: Executing the client code with a real subject:\n";
RealSubject *real_subject = new RealSubject;
ClientCode(*real_subject);
std::cout << "\n";
std::cout << "Client: Executing the same client code with a proxy:\n";
Proxy *proxy = new Proxy(real_subject);
ClientCode(*proxy);
delete real_subject;
delete proxy;
return 0;
}