代理模式的C++实现示例

核心思想

代理模式(Proxy Pattern)是一种结构型设计模式,其核心思想是为其他对象提供一个代理或占位符,以控制对这个对象的访问。代理对象通常会在客户端和目标对象之间起到中介作用,可以在不改变目标对象的情况下,增加额外的功能或控制访问。

解决的问题

代理模式主要解决以下问题:
​访问控制 :限制对目标对象的访问,例如权限控制、延迟加载等。
​功能增强 :在不修改目标对象的情况下,增加额外的功能,例如日志记录、性能监控等。
​远程代理 :为位于不同地址空间的对象提供本地代表,例如远程方法调用(RMI)。
​虚拟代理:延迟创建开销较大的对象,直到真正需要时才创建。

使用场景

延迟加载(Lazy Loading)​ :当对象的创建和初始化成本较高时,可以使用代理模式来延迟对象的创建,直到真正需要时才进行初始化。
​访问控制 :当需要对对象的访问进行控制时,可以使用代理模式来限制或过滤对目标对象的访问。
​日志记录 :当需要在访问对象时记录日志或进行审计时,可以使用代理模式来添加日志功能。
​远程代理:当需要访问远程对象时,可以使用代理模式来隐藏网络通信的复杂性。

优点:​

​职责清晰 :代理模式将客户端与目标对象解耦,使得职责更加清晰。
​扩展性强 :可以在不修改目标对象的情况下,通过代理对象增加额外的功能。
​控制访问:代理对象可以控制对目标对象的访问,例如权限控制、延迟加载等。

缺点:​

​增加复杂性 :引入代理对象会增加系统的复杂性,尤其是在需要多层代理时。
​性能开销:代理对象可能会引入额外的性能开销,尤其是在远程代理或虚拟代理的情况下。

示例代码

以下是一个简单的 C++11 代理模式示例,展示了如何使用代理模式来实现延迟加载和日志记录:

cpp 复制代码
#include <iostream>
#include <memory>
#include <string>

// 目标接口
class Subject {
public:
    virtual void Request() const = 0;
    virtual ~Subject() = default;
};

// 真实目标类
class RealSubject : public Subject {
public:
    void Request() const override {
        std::cout << "RealSubject: Handling Request." << std::endl;
    }
};

// 代理类
class Proxy : public Subject {
public:
    Proxy() : realSubject_(nullptr) {}

    void Request() const override {
        // 延迟加载真实对象
        if (!realSubject_) {
            realSubject_ = std::make_unique<RealSubject>();
        }
        std::cout << "Proxy: Logging before handling request." << std::endl;
        realSubject_->Request();
        std::cout << "Proxy: Logging after handling request." << std::endl;
    }

private:
    mutable std::unique_ptr<RealSubject> realSubject_;
};

// 模拟客户端代码
void ClientCode(const Subject& subject) {
    subject.Request();
}

int main() {
    std::cout << "Client: Executing the client code with a real subject:" << std::endl;
    RealSubject realSubject;
    ClientCode(realSubject);//这里客户端直接使用目标对象
	std::cout << std::endl;
    std::cout << "\nClient: Executing the client code with a proxy:" << std::endl;
    Proxy proxy;
    ClientCode(proxy);//这里客户端使用代理对象
    return 0;
}

输出结果

bash 复制代码
Client: Executing the client code with a real subject:
RealSubject: Handling Request.

Client: Executing the client code with a proxy:
Proxy: Logging before handling request.
RealSubject: Handling Request.
Proxy: Logging after handling request.

代码解析

​Subject :定义了目标接口,RealSubject 和 Proxy 都实现了这个接口。
​RealSubject :是真实的目标对象,负责实际的业务逻辑。
​Proxy :代理类,持有一个 RealSubject 的指针,并在 Request 方法中控制对 RealSubject 的访问。代理类在 Request 方法中增加了日志记录功能,并实现了延迟加载。
​ClientCode:客户端代码,通过 Subject 接口与目标对象交互,无需关心目标对象是 RealSubject 还是 Proxy。

总结

代理模式通过引入代理对象来控制对目标对象的访问,可以在不修改目标对象的情况下增加额外的功能或控制访问。它在延迟加载、访问控制、日志记录等场景中非常有用。然而,代理模式也会增加系统的复杂性和性能开销,因此在使用时需要权衡利弊。

相关推荐
码匠许师傅3 小时前
【C++ 面试真题】聊聊 C++ 的序列容器
java·c++·面试
C++ 老炮儿的技术栈3 小时前
Qt5.9.1 Windows 完整开发环境搭建流程
开发语言·c++·windows·qt·编辑器·代码化
键盘会跳舞4 小时前
C++:std::tuple 源码级深度拆解——变参模板、SFINAE与模板元编程核心技巧
开发语言·c++·sfinae·变参模板
bkspiderx4 小时前
从零开始:VS Code搭建C/C++开发环境全指南(Windows/macOS/Linux)
c语言·c++·windows·vs code·c/c++开发环境
东华万里4 小时前
第40篇C++核心基础与工程实践:从底层逻辑到避坑指南
开发语言·c++·面试·大学生专区
luj_17684 小时前
元设计的诱惑与现实
c语言·开发语言·c++·经验分享·算法
小星星闪亮登场4 小时前
ST表--倍增思想
开发语言·数据结构·c++·算法·思维
东华万里4 小时前
第40篇 C++核心基础与工程实践:从底层逻辑到避坑指南
开发语言·c++·大学生专区
AC赳赳老秦4 小时前
OpenClaw 多源采集公开行业数据:从原始信息到研究报告初稿的自动化实践
java·c语言·c++·python·php·deepseek·openclaw
玩三国杀玩的5 小时前
Pytorch-c++-CUDA
c++·pytorch·python·深度学习