C++实现设计模式---代理模式 (Proxy)

server/2025/1/18 2:24:49/

代理模式 (Proxy)

代理模式 是一种结构型设计模式,它为其他对象提供一个代理以控制对该对象的访问。代理模式常用于延迟加载、访问控制、智能引用等场景。


意图

  • 提供对某对象的控制。
  • 控制对目标对象的访问,通常用于在不改变目标对象的情况下,附加额外的功能。
  • 常见于延迟加载、权限控制等场景。

使用场景

  1. 远程代理

    • 当对象存在于不同的地址空间时,代理模式提供了对远程对象的访问。
  2. 虚拟代理

    • 延迟对象的创建,只有在需要时才创建对象,避免不必要的资源消耗。
  3. 保护代理

    • 控制对某个对象的访问权限。代理对象负责控制访问。
  4. 智能代理

    • 对对象访问进行计数、缓存等操作。例如,记录访问次数、管理缓存等。

参与者角色

  1. 主题接口 (Subject)

    • 定义了目标对象和代理类的公共接口。
  2. 真实主题 (RealSubject)

    • 实现了 Subject 接口的目标对象,包含实际业务逻辑。
  3. 代理 (Proxy)

    • 代理类,持有真实主题对象的引用,代理请求到真实主题对象,附加控制逻辑。

示例代码

以下代码展示了如何使用代理模式控制对一个图片加载的访问。

#include <iostream>
#include <string>// 主题接口
class Image {
public:virtual ~Image() = default;virtual void display() = 0; // 移除 const
};// 真实主题:加载并显示图片
class RealImage : public Image {
private:std::string filename;public:RealImage(const std::string& file) : filename(file) {loadImage();}void loadImage() const {std::cout << "Loading image: " << filename << std::endl;}void display() override {std::cout << "Displaying image: " << filename << std::endl;}
};// 代理类:代理真实图片加载和显示
class ProxyImage : public Image {
private:RealImage* realImage;std::string filename;public:ProxyImage(const std::string& file) : filename(file), realImage(nullptr) {}void display() override {if (!realImage) {realImage = new RealImage(filename);  // 延迟加载真实图像}realImage->display();}~ProxyImage() {delete realImage;}
};// 客户端代码
int main() {Image* image1 = new ProxyImage("image1.jpg");Image* image2 = new ProxyImage("image2.jpg");// 第一次访问时加载并显示图片image1->display();image2->display();// 直接显示图片,不会重新加载image1->display();delete image1;delete image2;return 0;
}

代码解析

1. 主题接口

  • Image 类定义了目标对象和代理类的公共接口。
  • 所有的图片类都需要实现 display 方法。
class Image {
public:virtual ~Image() = default;virtual void display() = 0;
};

2. 真实主题

  • RealImage 类是实际的图片对象,提供了加载和显示图片的功能。
  • loadImage 在构造函数中被调用,用于模拟加载图片。
class RealImage : public Image {
private:std::string filename;public:RealImage(const std::string& file) : filename(file) {loadImage();}void loadImage() const {std::cout << "Loading image: " << filename << std::endl;}void display() override {std::cout << "Displaying image: " << filename << std::endl;}
};

3. 代理类

  • ProxyImage 类是一个代理类,它控制对 RealImage 的访问。
  • display 方法中,它会先检查 realImage 是否已被创建。如果尚未创建,则延迟加载它。
class ProxyImage : public Image {
private:RealImage* realImage;std::string filename;public:ProxyImage(const std::string& file) : filename(file), realImage(nullptr) {}void display() override {if (!realImage) {realImage = new RealImage(filename);  // 延迟加载真实图像}realImage->display();}~ProxyImage() {delete realImage;}
};

4. 客户端

  • 客户端使用代理类,而不是直接使用真实主题类。
  • ProxyImage 控制了对 RealImage 的访问,并在必要时创建它。
int main() {Image* image1 = new ProxyImage("image1.jpg");Image* image2 = new ProxyImage("image2.jpg");image1->display(); // 加载并显示image2->display(); // 加载并显示image1->display(); // 直接显示delete image1;delete image2;
}

优缺点

优点

  1. 延迟初始化

    • 代理模式可以在需要时才创建和初始化对象,避免不必要的资源消耗。
  2. 控制访问权限

    • 代理对象可以控制对真实对象的访问,如权限控制、延迟加载等。
  3. 增加功能而不改变目标对象

    • 通过代理,可以为目标对象添加附加功能,而无需修改目标对象。

缺点

  1. 增加系统复杂度

    • 代理模式增加了对象间的间接性,可能导致系统变得复杂。
  2. 性能开销

    • 使用代理时,可能会有额外的性能开销,特别是在频繁调用代理方法时。

适用场景

  1. 远程代理

    • 访问远程对象时,代理对象可以替代真实对象,并处理通信。
  2. 虚拟代理

    • 延迟对象的加载,当需要时才创建对象,避免不必要的资源消耗。
  3. 保护代理

    • 控制对真实对象的访问权限,确保只有符合条件的用户才能访问。

总结

代理模式通过提供一个替代的对象来控制对真实对象的访问。它广泛用于延迟加载、权限控制、远程调用等场景,能够有效提高系统的灵活性和可扩展性。


http://www.ppmy.cn/server/159234.html

相关文章

【Flink系列】1.概述

1. Flink概述 1.1 Flink是什么 1.1.1 Flink是什么 Flink的官网主页地址&#xff1a;https://flink.apache.org/ 1.1.2 有界流和无界流 1.1.2 有状态流处理 1.1.3 Flink 的发展历史 1.2 Flink特点 1.3 Flink vs SparkStreaming 1.4 Flink 的应用场景 1.5 Flink 分层 API

深度学习camp-第J7周:对于ResNeXt-50算法的思考

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 &#x1f4cc;你需要解决的疑问&#xff1a;这个代码是否有错&#xff1f;对错与否都请给出你的思考 &#x1f4cc;打卡要求&#xff1a;请查找相关资料、逐步…

【认识油管头部频道】ep5 “5-Minute Crafts”——DIY 和生活技巧

5-Minute Crafts 是一个非常受欢迎的 DIY 和生活技巧频道&#xff0c;它的火爆有多方面的原因&#xff1a; 1. 简单实用的内容 视频主要以解决日常生活中遇到的小问题为主&#xff0c;提供简单易学的技巧&#xff0c;吸引了想快速获取实用知识的观众。 2. 短视频形式 每个视…

Elasticsearch技术标准解析与实践案例

一、引言 Elasticsearch(简称ES)是一个分布式、高扩展、高实时的搜索与数据分析引擎。它不仅能够进行全文搜索和分布式实时分析,还具备分布式的实时文档存储能力,支持上百个服务节点的扩展,并能处理PB级别的结构化或非结构化数据。本文旨在深入探讨Elasticsearch的技术原…

[Linux]——进程(2)

目录 ​编辑 一、前言 二、正文 2.1 进程状态 R/R状态 S状态 D状态 T/t状态 X状态 Z状态 2.2孤儿进程 2.3进程优先级 2.3.1基本概念 2.3.2PRI and NI 一、前言 在这一章&#xff0c;会为大家进行进程状态以及进程优先级的讲解 二、正文 2.1 进程状态 在一节中我们简…

idea上git log面板的使用

文章目录 各种颜色含义具体的文件的颜色标签颜色&#x1f3f7;️ 节点和路线 各种颜色含义 具体的文件的颜色 红色&#xff1a;表示还没有 git add 提交到暂存区绿色&#xff1a;表示已经 git add 过&#xff0c;但是从来没有 commit 过蓝色&#xff1a;表示文件有过改动 标…

视频点播共享系统项目

视频点播共享系统 一、项目功能二、开发环境三、技术特点四、项目模块1、数据管理模块2、网络通信模块3、业务处理模块4、前端界面模块 四、项目实现1、服务端工具类实现1.1 服务端工具类实现-文件实用工具类设计1.2 服务端工具类实现-Json实用工具类设计 2、服务端数据管理模块…

Tidb集群升级到8.5.0过程中服务器遇到的坑

TiDB 集群升级到8.5.0踩坑记&#xff1a;从 GLIBC_2.15 升级到 GLIBC_2.28YUM 仓库问题的全面解决 1. 引言 作为部门的负责人&#xff0c;我常常觉得自己是个“救火队员”。昨天 TiDB 集群又出问题了&#xff1a;查询卡顿、响应时间变长&#xff0c;重启之后问题依旧。临近下班…