C++设计模式之代理模式(Proxy)
代理模式是一种结构型设计模式,它允许将对象的访问控制在另一个对象中,从而在访问对象时提供间接的方式。代理模式允许我们通过使用另一个对象来代表实际的对象来控制对实际对象的访问。
适用场景
在以下情况下使用代理模式:
- 当直接访问对象可能会危及对象的安全时。
- 当访问一个对象需要很长时间时,因为每次访问都需要进行复杂的计算,而无需每次都计算。
- 当需要在没有访问对象的基础上执行额外的操作时,例如对访问对象进行计数或访问日志。
实现方法
代理模式由两个角色组成:代理和实体。代理和实体都实现相同的接口。代理持有一个指向实体的引用,以及自身的属性。当客户端通过代理访问对象时,代理检查客户端是否有足够的权限,然后将调用传递给实体。
class Subject {
public:
virtual void request() = 0;
};
class RealSubject : public Subject {
public:
void request() override {
std::cout << "RealSubject: Handling request.\n";
}
};
class Proxy : public Subject {
private:
RealSubject *real_subject_;
bool check_access() const {
std::cout << "Proxy: Checking access prior to firing a real request.\n";
return true;
}
void log_access() const {
std::cout << "Proxy: Logging the time of request.\n";
}
public:
Proxy(RealSubject *real_subject) : real_subject_(new RealSubject(*real_subject)) {
}
~Proxy() {
delete real_subject_;
}
void request() override {
if (this->check_access()) {
this->real_subject_->request();
this->log_access();
}
}
};
上述代码演示了一个简单的代理模式。该代码包含三个类:Subject、RealSubject和Proxy。Subject类表示抽象接口,RealSubject类表示真实对象,Proxy类表示代理。实体和代理都遵循相同的接口。
Proxy类持有一个指向RealSubject对象的指针,并检查客户端是否有访问对象的权限。如果客户端具有访问权限,则代理将请求传递给RealSubject对象,并在代理中记录访问。
示例1:保护代理
代码演示了如何使用保护代理来控制对RealSubject对象的访问。
class RealSubject {
public:
void request() const {
std::cout << "RealSubject: Handling request.\n";
}
};
class Proxy {
private:
const RealSubject& real_subject_;
bool check_access() const {
// 一些复杂的验证逻辑。
std::cout << "Proxy: Checking access prior to firing a real request.\n";
return true;
}
public:
Proxy(const RealSubject& real_subject) : real_subject_(real_subject) {}
void request() const {
if (this->check_access()) {
this->real_subject_.request();
}
}
};
void client_code(const Proxy& proxy) {
// ...
proxy.request();
// ...
}
int main() {
RealSubject* real_subject = new RealSubject;
Proxy* proxy = new Proxy(*real_subject);
client_code(*proxy);
delete real_subject;
delete proxy;
return 0;
}
示例2: 虚拟代理
代码演示了如何使用虚拟代理来延迟对RealSubject对象的创建和初始化。
class RealSubject {
public:
RealSubject() {
std::cout << "RealSubject: Created.\n";
}
void request() const {
std::cout << "RealSubject: Handling request.\n";
}
};
class Proxy {
private:
RealSubject* real_subject_;
bool check_access() const {
// 一些复杂的验证逻辑。
std::cout << "Proxy: Checking access prior to firing a real request.\n";
return true;
}
public:
Proxy() : real_subject_(nullptr) {}
~Proxy() {
delete real_subject_;
}
void request() const {
if (!real_subject_) {
real_subject_ = new RealSubject;
}
if (this->check_access()) {
this->real_subject_->request();
}
}
};
void client_code(const std::vector<Proxy*>& proxies) {
// ...
for (const Proxy* proxy : proxies) {
proxy->request();
}
// ...
}
int main() {
std::vector<Proxy*> proxies;
proxies.push_back(new Proxy);
client_code(proxies);
for (const Proxy* proxy : proxies) {
delete proxy;
}
return 0;
}
在上面的示例中,客户端执行了许多将请求传递给代理的操作。每次执行操作时,代理都必须检查访问权限并将请求转发给真实的主体对象。
此过程效率很低,因为在每个操作之间都要重复这些步骤。为了解决这个问题,可以使用虚拟代理。
使用虚拟代理时,真实主题对象将被延迟创建或初始化。虚拟代理只在必要时才会创建真实对象。在实际场景中,真实对象可能会在远程服务器上运行,或者可能非常大,需要很长时间才能初始化。在客户端等待真实对象初始化的过程中,代理可以做一些小的验证和验证操作。
总结
代理模式是一种结构型设计模式。它使代码更具模块性,并允许我们将对象的访问控制在另一个对象中。我们可以在代理中添加对客户端的额外检查和验证。在某些情况下,代理可以延迟对象的创建或初始化,以优化代码的性能和运行速度。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++设计模式之代理模式(Proxy) - Python技术站