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

ops/2025/1/14 19:31:06/

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

相关文章

第21篇 基于ARM A9处理器用汇编语言实现中断<三>

Q&#xff1a;怎样编写ARM A9处理器汇编语言代码配置按键端口产生中断&#xff1f; A&#xff1a;使用Intel Monitor Program创建中断程序时&#xff0c;Linker Section Presets下拉菜单中需选择Exceptions。主程序在.vectors代码段为ARM处理器设置异常向量表&#xff0c;在…

大语言模型预训练、微调、RLHF

转发&#xff0c;如有侵权&#xff0c;请联系删除&#xff1a; 1.【LLM】3&#xff1a;从零开始训练大语言模型&#xff08;预训练、微调、RLHF&#xff09; 2.老婆饼里没有老婆&#xff0c;RLHF里也没有真正的RL 3.【大模型微调】一文掌握7种大模型微调的方法 4.基于 Qwen2.…

ref useRef React.createRef React.forwardRef

react如何获取真实DOM&#xff1a;useRef, React.CreateRef() access DOM nodes directly within React&#xff1a;ref.current Let’s say you want to change the value of an <input> element, but without using props or re-rendering the whole component. They’…

PyCharm 的安装与使用(Window)

1 PyCharm 简介 PyCharm 是一款由 JetBrains 公司开发的专门用于 Python 语言开发的集成开发环境&#xff08;IDE&#xff09;。以下是其相关介绍&#xff1a; 1.1 特点与功能 智能代码编辑&#xff1a;提供高度智能化的代码编辑器&#xff0c;支持语法高亮、自动补全、代码重…

四阶龙格库塔法求解二元二阶常微分方程

龙格库塔法&#xff08;Runge-Kutta methods&#xff09;是用于非线性常微分方程的解的重要的一类隐式或显式迭代法。在工程领域应用广泛&#xff0c;可用于求解复杂系统的运动方程等问题。 这里采用matlab程序编写代码实现龙格库塔法对于二元二阶常微分方程的求解。 例 { x …

Qt重写webrtc的demo peerconnection

整个demo为&#xff1a; 可以选择多个编码方式&#xff1a; cmake_minimum_required(VERSION 3.5)project(untitled LANGUAGES CXX) set(CMAKE_CXX_STANDARD 20) set(CMAKE_INCLUDE_CURRENT_DIR ON)set(CMAKE_AUTOUIC ON) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON)set(CMA…

leetcode - 916. Word Subsets

Description You are given two string arrays words1 and words2. A string b is a subset of string a if every letter in b occurs in a including multiplicity. For example, “wrr” is a subset of “warrior” but is not a subset of “world”. A string a from …

如何将 sqlserver 数据迁移到 mysql

文章目录 前言一、导出SQL Server 数据二、转换数据格式为MySQL兼容格式三、导入数据到MySQL数据库五、使用ETL工具六、通过 navicat 工具七、总结 前言 将 SQL Server 数据迁移到 MySQL 是一个常见的数据库迁移任务&#xff0c;通常涉及以下几个关键步骤&#xff1a;导出 SQL…