当前位置: 首页 > article >正文

13.代理模式(Proxy Pattern)

定义

代理模式(Proxy Pattern) 是一种结构型设计模式,它通过提供一个代理对象来控制对目标对象的访问。代理对象作为客户端与目标对象之间的中介,间接地访问目标对象的功能。代理模式可以在不改变目标对象的情况下增加一些额外的功能,如延迟加载、安全控制、日志记录等。

基本思想

代理对象:代理模式引入了一个中介对象(代理对象)来访问真实的对象。代理对象控制对真实对象的访问,并可以在访问真实对象之前或之后加入额外的功能。
目标对象:代理模式的核心是需要被代理的对象,它实现了实际的业务逻辑。
客户端:客户端通过代理对象间接调用目标对象的方法,而不直接访问目标对象。

适用场景

代理模式适用于以下场景:

  • 控制访问:当需要控制对某个对象的访问时,可以使用代理模式。比如,代理模式可以限制某些操作,或者在目标对象没有初始化时,延迟加载目标对象。
  • 延迟加载:在需要时才创建目标对象,而不是在系统初始化时创建,这样可以节省资源。
  • 缓存:通过代理模式,代理对象可以缓存目标对象的结果,避免重复计算。
  • 日志记录:代理对象可以在方法执行前后记录日志,确保目标对象的行为被正确监控。
  • 远程访问:代理模式可用于实现远程访问对象,客户端与代理对象交互,而代理对象负责与远程目标对象进行通信。

类设计

代码实现解析

  1. 设计目标:代理模式实现任务处理
    我们设计一个简单的场景,其中 ISubject 是任务处理接口,RealSubject 是具体的任务处理类,SubjectProxy 是代理类,它负责对 RealSubject 的间接访问。
#include <iostream>
#include <string>
using namespace std;

// 定义Subject接口
class ISubject {
public:
    virtual void process() = 0;
    virtual ~ISubject() {}
};

// 真实主题类(RealSubject)
class RealSubject : public ISubject {
public:
    void process() override {
        cout << "RealSubject: Processing the task." << endl;
    }
};

// 代理类(SubjectProxy)
class SubjectProxy : public ISubject {
private:
    RealSubject* realSubject;

public:
    SubjectProxy() : realSubject(nullptr) {}

    void process() override {
        // 代理对象在访问目标对象之前做一些处理(如延迟加载、权限检查等)
        cout << "Proxy: Checking access rights..." << endl;
        if (!realSubject) {
            // 延迟加载目标对象
            realSubject = new RealSubject();
            cout << "Proxy: Creating RealSubject instance..." << endl;
        }
        // 代理对象调用真实主题的方法
        realSubject->process();
    }

    ~SubjectProxy() {
        delete realSubject;  // 确保释放真实主题对象的资源
    }
};

// 客户端类
class ClientApp {
private:
    ISubject* subject;

public:
    ClientApp() {
        subject = new SubjectProxy();  // 客户端通过代理类访问任务
    }

    void DoTask() {
        // 客户端通过代理对象执行任务
        subject->process();
    }

    ~ClientApp() {
        delete subject;
    }
};

int main() {
    ClientApp app;
    app.DoTask();  // 通过代理对象处理任务
    return 0;
}

输出:

Proxy: Checking access rights...
Proxy: Creating RealSubject instance...
RealSubject: Processing the task.

客户端通过 ClientApp 调用 subject->process(),
但实际执行的是通过 SubjectProxy 代理对象的 process() 方法。

代理对象首先检查访问权限(这里是模拟操作),
然后如果目标对象尚未创建,则延迟创建 RealSubject 实例并执行任务。

类设计分析

1.ISubject(接口/抽象类)

  • 定义了代理类和真实对象共同的接口。在本例中,process() 方法是客户端与代理类和真实类交互的唯一方式。

2.RealSubject(真实主题)

  • RealSubject 是实际执行任务的类,它提供了业务逻辑的实现。
  • 在 process() 方法中,RealSubject 处理实际的任务。

3.SubjectProxy(代理类):

  • 代理类实现了 ISubject 接口,负责控制对 RealSubject 的访问。代理类可以在调用 RealSubject 的方法之前执行一些操作(如延迟加载、权限验证、日志记录等)。
  • 在 process() 方法中,代理对象会检查是否已经创建了 RealSubject 实例,如果没有,则创建一个实例并调用 process()。

4.ClientApp(客户端):

  • 客户端通过 ISubject 接口与 SubjectProxy(代理对象)交互,而不直接与 RealSubject 进行交互。客户端只调用 process() 方法,而无需关心代理对象如何处理目标对象的访问。

代理模式的优缺点

优点:

  • 控制访问:代理模式可以控制对目标对象的访问,并增加附加功能,如懒加载、日志、权限验证等。
  • 提高效率:通过延迟加载(懒加载),可以在需要时才创建目标对象,从而节省资源。
  • 解耦:客户端不需要直接与目标对象交互,代理类充当了客户端和目标对象之间的中介,降低了系统的耦合性。
  • 附加功能:可以在代理类中为目标对象添加额外的功能,如缓存、日志、权限检查等,而不修改目标对象的代码。

缺点

  • 增加复杂度:代理模式通过引入额外的类增加了系统的复杂度,特别是在目标对象复杂时。
  • 性能开销:代理类通常会引入一定的性能开销,尤其是在频繁的代理操作中,可能会影响系统的性能。
  • 不可避免的代理层:代理模式在某些情况下可能导致不必要的中间层,尤其是当目标对象的接口已经足够简洁时。

适用场景

代理模式适用于以下场景:

  • 延迟加载:当对象的创建成本较高时,可以使用代理模式进行延迟加载。
  • 访问控制:当需要对目标对象的访问进行控制时(如权限验证、缓存等),可以使用代理模式。
  • 资源保护:代理模式可用于保护目标对象的资源,如防止频繁创建和销毁实例。
  • 远程代理:在分布式系统中,代理模式可以用来控制客户端与远程对象之间的通信。

常见应用场景:

  • 虚拟代理:延迟加载目标对象,直到真正需要它时才创建实例。
  • 保护代理:限制客户端对某些操作的访问,进行权限检查。
  • 远程代理:客户端通过代理与远程对象进行交互,代理负责与远程服务器通信。
  • 智能代理:增加一些额外的功能,如缓存、日志、事务管理等。

总结

代理模式通过引入代理类,允许客户端通过代理间接访问目标对象,并能在不改变目标对象的情况下,增加一些额外的功能,如延迟加载、访问控制、日志记录等。代理模式能有效地解耦客户端和目标对象,简化客户端与目标对象之间的交互,同时增加系统的灵活性。


http://www.kler.cn/a/533666.html

相关文章:

  • 用 Python 绘制爱心形状的简单教程
  • 2025最新软件测试面试大全
  • 排序算法--归并排序
  • Math数字类
  • 【Elasticsearch】 Intervals Query
  • 差值 dp 入门
  • mini-lsm通关笔记Week2Day7
  • 将OneDrive上的文件定期备份到移动硬盘
  • 闲聊邵雍的“象数”与古诗有感
  • 从51到STM32:PWM平滑迁移方案
  • make -j$(nproc)——多核加速编译
  • 《Java核心技术 卷II》本地日期
  • 01vue3实战-----前言
  • VSCode中使用EmmyLua插件对Unity的tolua断点调试
  • Go语言并发之美:构建高性能键值存储系统
  • 动静态库的学习
  • golang命令大全11--命令的常见问题与解决方案
  • pandas获取指定日期的行
  • 网络爬虫会对服务器造成哪些影响?
  • 每日Attention学习19——Convolutional Multi-Focal Attention
  • Java学习进阶路线
  • 标准库发送数据深入理解USART
  • Windows下安装mkcert
  • 9. k8s二进制集群之kube-controller-manager部署
  • TensorFlow深度学习实战(6)——回归分析详解
  • Deepseek技术浅析(四):专家选择与推理机制