代理模式的核心是通过替身控制对真实对象的访问,其目的是在不修改真实对象的前提下实现延迟加载、权限控制等额外逻辑。要实现代理模式,首先要定义共同接口subject,让realsubject和proxy都实现它;其次代理持有真实对象的引用,并在其方法中加入前置或后置处理逻辑;最后根据需求扩展虚拟代理或保护代理。虚拟代理侧重按需加载,适用于资源占用大的场景;保护代理则用于权限检查,确保系统安全。这种设计提升了系统的灵活性、可维护性与安全性。

C++中实现代理模式,本质上是在不直接接触真实对象的情况下,通过一个“替身”来控制对真实对象的访问。虚拟代理常用于延迟加载资源,优化性能,而保护代理则侧重于访问权限控制,确保系统安全。这两种代理模式各有侧重,但都旨在提供更灵活、更安全的面向对象设计。

要实现C++的代理模式,核心在于定义一个共同的接口(Subject),让真实对象(RealSubject)和代理对象(Proxy)都实现它。代理对象内部持有真实对象的引用,并在自己的方法中调用真实对象的方法,但在此之前或之后加入额外的逻辑。
一个典型的结构会是这样:
立即学习“C++免费学习笔记(深入)”;

#include <iostream>
#include <string>
#include <chrono> // For std::this_thread::sleep_for
#include <thread> // For std::this_thread
// 共同接口
class Subject {
public:
    virtual void request() = 0;
    virtual ~Subject() = default;
};
// 真实对象
class RealSubject : public Subject {
public:
    void request() override {
        // 真实对象执行核心业务逻辑
        // 比如:加载大型图片、执行耗时计算、访问敏感数据
        std::cout << "RealSubject: Handling request." << std::endl;
    }
};
// 代理对象基类(可以抽象出,也可以直接实现特定代理)
// 这里以一个通用的代理为例
class GeneralProxy : public Subject {
protected:
    RealSubject* realSubject; // 代理持有真实对象的引用
public:
    GeneralProxy() : realSubject(nullptr) {} // 默认构造,可能在需要时才创建RealSubject
    ~GeneralProxy() {
        delete realSubject; // 清理资源
    }
    // 代理的核心:在调用真实方法前后加入逻辑
    void request() override {
        // 这是通用代理的模板,具体代理会重写此方法
        if (!realSubject) {
            // 假设这里是虚拟代理的创建逻辑
            realSubject = new RealSubject();
            std::cout << "GeneralProxy: Creating RealSubject on demand." << std::endl;
        }
        // 在调用真实方法前可以做些什么
        std::cout << "GeneralProxy: Pre-processing request." << std::endl;
        realSubject->request();
        // 在调用真实方法后可以做些什么
        std::cout << "GeneralProxy: Post-processing request." << std::endl;
    }
};实际应用中,虚拟代理和保护代理会在此基础上增加特有的逻辑。例如,虚拟代理会在 request 首次调用时才创建 RealSubject 实例;保护代理则会在 request 调用前检查调用者的权限。
代理模式,说白了,就是给一个对象找个“替身”。这个替身(Proxy)和原对象(RealSubject)实现同一个接口,所以客户端代码完全不知道自己打交道的是替身还是真身。这听起来有点像在玩“障眼法”,但它的价值可不小。

我个人觉得,代理模式最迷人的地方在于它提供了一种“间接性”的控制。我们不需要直接修改真实对象的代码,就能在它被访问时,或者访问它之后,插入各种额外的逻辑。这对于那些我们无法修改、不应该修改或者修改成本很高的第三方库、遗留系统中的类尤其有用。
为什么要用它?想象一下,你有一个非常“重”的对象,比如加载一张几百兆的图片,或者从一个远程数据库拉取大量数据。你肯定不希望在程序启动时就把所有这些东西都加载进来,那样程序会慢得像蜗牛。这时候,代理就能派上用场了。它可以在你真正需要这些数据的时候,才去加载它们。这就是一种性能优化,一种延迟加载的策略。
再比如,你有一个核心的业务逻辑对象,但不是所有用户都能访问它的所有功能。有些功能只允许管理员操作,有些只允许普通用户查看。你当然可以在真实对象的方法里写一堆 if (user.role == ADMIN) 这样的判断,但那样会把真实对象的代码搞得一团糟,而且职责也不清晰。这时候,代理就可以在访问真实对象之前,先检查一下用户的权限。权限不够?直接拒绝访问,连真实对象一眼都看不到。这不就是一种优雅的访问控制吗?
所以,核心理念就是:通过引入一个中间层,在不改变原有接口的前提下,对真实对象的访问进行控制、增强或限制。它提供了一种解耦的方案,让我们可以把一些非核心的、横切的关注点(比如延迟加载、访问控制、日志记录、缓存等)从真实对象中剥离出来,保持真实对象的纯粹性,同时提升系统的灵活性和可维护性。在我看来,这是一种非常“面向对象”的思考方式,把职责划分得清清楚楚。
虚拟代理,顾名思义,就是一种“假”的代理,它在开始时并不持有真实对象的实例,而是在真实对象第一次被需要时才去创建它。这与那些一开始就持有真实对象引用的代理(比如保护代理或远程代理)形成了鲜明对比。它的核心思想就是“按需加载”(Lazy Loading)。
我记得有一次,我手头一个项目需要显示一个包含大量高分辨率图片的列表。如果我直接在列表加载的时候就把所有图片都加载到内存里,那程序启动速度会非常慢,而且内存占用会爆炸。用户可能根本不会滚动到列表的底部,或者根本不会点击查看所有图片。这时候,虚拟代理简直是救星。
它的实现通常是这样的:代理对象在构造时并不会创建真实对象,而是持有一个指向真实对象类型,但初始为空的指针。当客户端代码第一次调用代理的某个方法时,代理会检查这个指针是否为空。如果为空,它就负责创建真实对象的实例,然后将后续的请求转发给这个新创建的真实对象
以上就是怎样实现C++的代理模式 虚拟代理与保护代理应用场景的详细内容,更多请关注php中文网其它相关文章!
 
                        
                        每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
 
                Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号