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

embedded/2025/1/14 20:21:11/

代理模式 (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/embedded/153922.html

相关文章

【PyQt】如何在mainwindow中添加菜单栏

[toc]如何在mainwindow中添加菜单栏 如何在mainwindow中添加菜单栏 主要有两种方法&#xff1a; 1.直接创建mainwindow进行添加 2.使用ui文件加载添加 第二种方法更为常见&#xff0c;可以应用到实际 1.直接创建mainwindow进行添加 import sysfrom PyQt5.QtWidgets import …

Spring Boot + MyBatis Plus 存储 JSON 或 List 列表全攻略

在现代的后端开发中&#xff0c;我们常常需要处理复杂的数据结构&#xff0c;JSON 数据以及列表&#xff08;List&#xff09;数据屡见不鲜。如何高效地使用 Spring Boot 和 MyBatis Plus 来存储这些复杂数据类型&#xff0c;是这篇博客要探讨的重点。 一、为什么要存储 JSON …

CentOS 和 Ubantu你该用哪个

文章目录 **一、CentOS 和 Ubuntu 的详细介绍****1. CentOS****1.1 基本信息****1.2 特点****1.3 缺点** **2. Ubuntu****2.1 基本信息****2.2 特点****2.3 缺点** **二、CentOS 和 Ubuntu 的异同****1. 相同点****2. 不同点****3. 使用体验对比** **三、总结和选择建议** Cent…

科技赋能:多功能气膜综合馆引领场馆新革命—轻空间

在现代体育场馆建设中&#xff0c;如何为运动员提供更佳的比赛环境&#xff0c;为观众营造更舒适的观赛体验&#xff0c;已成为场馆设计的关键课题。而多功能气膜综合馆以其独特的声学优化技术和卓越的场馆功能&#xff0c;成功突破了传统气膜场馆的局限&#xff0c;为运动体验…

macOS 版本对应 Xcode 版本,以及 Xcode 历史版本下载

注&#xff1a;当前页面的所有Xcode下载链接均为苹果官方下载链接 &#xff0c;点击将直接转至苹果官网下载。❤️❤️❤️ Xcode官网&#xff1a;Xcode Releases | xcodereleases.com Xcode版本Xcode发布时间对应macOS版本macOS SDKsiOS SDKswatchOS SDKstvOS SDKs下载Xcode发…

后台管理系统-axios网络请求的封装

此博客是针对开源项目:vue3-element-admin 的学习记录,为了帮助自己理清开发这个系统的逻辑. 安装依赖 npm install axios , qsAxios实例封装 // 创建 axios 实例 ,同时给出一些预设配置&#xff0c;比如baseURL&#xff0c;超时时间等等 const service axios.create({base…

idea快捷键

IDEA常见快捷键 Ctrl A 全写 Ctrl C 粘贴 Ctrl V 复制 Ctrl F 搜索 Ctrl R 替换 Ctrl Z 撤销 Ctrl D 复制行 Ctrl X 删除行&#xff0c;并且被删除的行复制到剪贴板中 Ctrl Y 删除一行 Ctrl Shift Z 反撤销 IDEA重要快捷键 Ctrl / 单行注释&…

汇总统计数据--SQL中聚集函数的使用

目录 1、为什么需要汇总数据 2、聚集函数 &#xff08;1&#xff09;AVG函数 &#xff08;2&#xff09;COUNT函数 &#xff08;3&#xff09;MAX和MIN函数 &#xff08;4&#xff09;SUM函数 3、聚集不同值--DISTINCT 4、组合聚集函数 5、小结 博主用的是mysql8 DBMS…