重温设计模式--代理模式
文章目录
- 定义
- UML图
- 代理模式主要有以下几种常见类型:
- 代理模式涉及的主要角色有:
- C++ 代码示例
定义
代理模式(Proxy Pattern)属于结构型设计模式,它为其他对象提供一种代理以控制对这个对象的访问。
通过引入代理对象,代理模式可以在目标对象的基础上,增加额外的功能,比如访问控制、懒加载、缓存等,同时对外界隐藏目标对象的实现细节,让调用者感觉好像是在直接与目标对象进行交互。
UML图

代理模式主要有以下几种常见类型:
远程代理(Remote Proxy):用于代表一个在不同地址空间(比如网络上的不同服务器)的对象,使得客户端可以像访问本地对象一样访问远程对象。
虚拟代理(Virtual Proxy):根据需要创建开销较大的对象,比如在真正需要访问对象时才去实例化它,常用于实现图片懒加载等功能,在图片要显示时才加载图片资源。
保护代理(Protection Proxy):控制对原始对象的访问权限,根据不同的权限决定是否允许调用者执行相应的操作。
代理模式涉及的主要角色有:
抽象主题(Subject):定义了真实主题和代理主题的共同接口,这样客户端在使用时可以以统一的方式与真实对象或代理对象进行交互。
真实主题(Real Subject):实现了抽象主题接口,是实际完成业务逻辑的对象,也就是被代理的对象。
代理(Proxy):同样实现了抽象主题接口,内部包含一个指向真实主题对象的指针,它可以在调用真实主题的方法前后添加额外的逻辑,来实现对真实主题的访问控制等功能。
C++ 代码示例
以下是一个简单的代理模式示例,模拟一个简单的图像加载展示场景,这里使用虚拟代理的思路,先创建代理对象,在真正需要展示图像(调用 display 方法)时才去加载并展示真实的图像(这里只是简单模拟加载逻辑)。
#include <iostream>
#include <string>// 抽象主题,定义图像操作的接口
class Image
{
public:virtual void display() = 0;virtual ~Image() {}
};// 真实主题,代表实际的图像,这里简单模拟图像有个文件名属性及加载展示逻辑
class RealImage : public Image
{
private:std::string fileName;
public:RealImage(const std::string& name) : fileName(name) {loadFromDisk();}void display() override{std::cout << "Displaying image: " << fileName << std::endl;}
private:void loadFromDisk(){std::cout << "Loading image from disk: " << fileName << std::endl;}
};// 代理类,代表图像的代理,在需要时才创建真实图像对象并调用其方法
class ProxyImage : public Image
{
private:RealImage* realImage;std::string fileName;
public:ProxyImage(const std::string& name) : realImage(nullptr), fileName(name) {}void display() override{//在此,可以对被代理的对象的操作进行额外操作;//不允许显示特定的图片,异常处理,或者重新解码显示,加水印等等任何实际需求都可以在此添加if (!realImage){realImage = new RealImage(fileName);}realImage->display();}~ProxyImage() {delete realImage;}
};int main()
{// 创建代理对象,此时并没有真正加载图像Image* image = new ProxyImage("example.jpg");// 第一次调用 display,会触发真实图像的加载和展示image->display();// 第二次调用 display,因为已经加载过了,直接展示,不会重复加载image->display();delete image;char t;std::cin>>t;return 0;
}

在上述代码中:
Image 作为抽象主题,定义了 display 这个抽象方法,表示图像展示的操作,客户端只需要和这个接口进行交互。
RealImage 是真实主题,它实现了 Image 接口,内部有图像文件名属性,并且在构造函数中会进行从磁盘加载图像的模拟操作,在 display 方法中展示图像。
ProxyImage 为代理类,它也实现了 Image 接口,内部有一个指向 RealImage 的指针以及图像文件名属性。在 display 方法中,先判断真实图像是否已经创建,如果没有创建就实例化 RealImage,然后调用真实图像的 display 方法来展示图像。这样就实现了在真正需要展示图像时才去加载它的虚拟代理功能,并且在 main 函数里可以看到,多次调用展示方法时,后续调用不会重复加载图像,提高了效率(在更复杂的场景下能体现出资源利用等方面的优势)。最后要记得释放内存,避免内存泄漏。
仔细想一下,智能指针好像有点代理模式的意思。
相关文章:
重温设计模式--代理模式
文章目录 定义UML图代理模式主要有以下几种常见类型:代理模式涉及的主要角色有:C 代码示例 定义 代理模式(Proxy Pattern)属于结构型设计模式,它为其他对象提供一种代理以控制对这个对象的访问。 通过引入代理对象&am…...
一些elasticsearch重要概念与配置参数
ES 是在 lucene 的基础上进行研发的,隐藏了 lucene 的复杂性,提供简单易用的 RESTful Api接口。ES 的分片相当于 lucene 的索引。 Node 节点的几种部署实例 实例一: 只用于数据存储和数据查询,降低其资源消耗率 node.master: false node.da…...
leetcode 面试经典 150 题:螺旋矩阵
链接螺旋矩阵题序号54题型二维数组(矩阵)解题方法模拟路径法难度中等熟练度✅✅✅ 题目 给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。 示例 1: 输入:matrix [[1,2,3…...
JAVA AOP简单实践(基于SpringBoot)
天行健,君子以自强不息;地势坤,君子以厚德载物。 每个人都有惰性,但不断学习是好好生活的根本,共勉! 文章均为学习整理笔记,分享记录为主,如有错误请指正,共同学习进步。…...
java agent的使用【通俗易懂版】
一、静态代理Agent 1.生成Agent的jar包 (1)创建Agent项目,引入javassist.jar包 (2)编写premain方法 import java.lang.instrument.Instrumentation;public class Agent1 {public static void premain(Stri…...
大模型学习指南
随着人工智能的迅猛发展,大模型成为了技术前沿的璀璨明星。踏入大模型学习领域,需要在多个关键方面下功夫。 扎实的数学功底是基石。线性代数为理解多维数据、矩阵运算提供支撑,像大模型中权重矩阵的处理就离不开它;概率论与数理…...
单片机:实现定时器中断(数码管读秒+LED闪烁)(附带源码)
单片机实现定时器中断:数码管读秒与LED闪烁 在单片机项目中,定时器中断是一个常见的应用,用于实现定时任务,例如定时更新显示或控制周期性事件。本文将介绍如何使用定时器中断实现数码管读秒和LED闪烁功能。通过使用定时器中断&a…...
STM32单片机芯片与内部33 ADC 单通道连续DMA
目录 一、ADC DMA配置——标准库 1、ADC配置 2、DMA配置 二、ADC DMA配置——HAL库 1、ADC配置 2、DMA配置 三、用户侧 1、DMA开关 (1)、标准库 (2)、HAL库 2、DMA乒乓 (1)、标准库 ÿ…...
【0376】Postgres内核 分配 last safe MultiXactId
上一篇: 【0375】Postgres内核 XLOG 之 设置下一个待分配 MultiXactId 和 offset 文章目录 1. 最后一个安全的 MultiXactId1.1 计算 multi wrap limit1.2 计算 multi stop limit1.3 计算 multi warn limit1.4 计算 multi vacuum limit2. 初始化 MultiXactState 成员3. 完成 mu…...
php时间strtotime函数引发的问题 时间判断出错
在 PHP 中,strtotime 函数能处理的最大时间范围取决于您的系统和 PHP 版本。 一般来说,它可以处理的时间范围从 1901 年 12 月 13 日到 2038 年 1 月 19 日。超过这个范围可能会导致不可预测的结果或错误。 如果您需要处理更大范围的时间,可能…...
Kibana:LINUX_X86_64 和 DEB_X86_64两种可选下载方式的区别
最近需要在vm(操作系统是 Ubuntu 22.04.4 LTS,代号 Jammy。这是一个基于 x86_64 架构的 Linux 发行版)上安装一个7.17.8版本的Kibana,并且不采用docker方式。 在下载的时候发现有以下两个选项,分别是 LINUX_X86_64 和 …...
【LeetCode每日一题】 LeetCode 151.反转字符串中的单词
LeetCode 151.反转字符串中的单词 题目描述 给你一个字符串 s ,请你反转字符串中单词的顺序。 单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。 返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。 注意:…...
gitlab克隆仓库报错fatal: unable to access ‘仓库地址xxxxxxxx‘
首次克隆仓库,失效了,上网查方法,都说是网络代理的问题,各种清理网络代理后都无效,去问同事: 先前都是直接复制的网页url当做远端url,或者点击按钮‘使用http克隆’ 这次对于我来说有效的远端u…...
在已有vue cli项目中添加单元测试配置
使用的是vue cli ^4.0.0的脚手架,项目采用的vue2进行编写,项目本身是没有使用单元测试的。应该挺多项目还是使用的vue2的项目进行开发的,自己在开发中过程中,还是发生了挺多需要记录原来功能的情况,这个时候去翻文档明…...
企业级NoSql数据库REDIS集群
1.1数据库主要分为两大类:关系型数据库与 NoSQL数据库 关系型数据库,是建立在关系模型基础上的数把库,其借助于集合代数等数学概念和方法来处理数据库中的数掘主流的 MySQLOracle、Ms sOLSerer和 DB2 都属于这类传统数据库 NoSQL数据库,全称…...
HTML与数据抓取:GET与POST方法详解
讲GET和POST就不能只讲GET和POST 你要讲HTTP请求的基本概念: HTTP(HyperText Transfer Protocol,超文本传输协议)是互联网上应用最为广泛的一种网络协议,主要用于Web浏览器与Web服务器之间的数据通信。HTTP是一个基于…...
【es6复习笔记】模板字符串(3)
介绍 模板字符串是 ES6 引入的一种新的字符串声明方式,它使用反引号()来定义字符串,而不是单引号()或双引号(")。模板字符串可以包含变量、表达式和换行符,这使得它…...
cursor保存更改操作技巧
1. 当我们在agent模式时,要求cursor更改代码时,cursor回答后,就已经更改了代码了,这时候就可以对程序进行编译和测试, 不一定先要点” accept“, 先测试如果没有问题再点“accept”,这样composer就会多一条…...
ASP.NET |日常开发中定时任务详解
ASP.NET |日常开发中定时任务详解 前言一、定时任务的概念与用途1.1 定义1.2 应用场景 二、在ASP.NET中实现定时任务的方式2.1 使用System.Timers.Timer2.2 使用Quartz.NET 三、定时任务的部署与管理3.1 部署考虑因素3.2 管理与监控 结束语优质源码分享 ASP.NET &am…...
【零基础保姆级教程】制作自己的数据集(二)——Labelme的安装与使用及常见的报错解决方法
前段时间安装了Labelimg,网上有些博客写着Labelme能进行语义分割的标注,但UI窗口就那么大找不着选项,只能打矩形框,为了能够标注自己的分割数据集,遂写下该教程以供参考。 采用Labelimg进行目标检测标注的教程如下。 …...
如何使用HS2-HF_Patch优化Honey Select 2游戏体验:完整指南
如何使用HS2-HF_Patch优化Honey Select 2游戏体验:完整指南 【免费下载链接】HS2-HF_Patch Automatically translate, uncensor and update HoneySelect2! 项目地址: https://gitcode.com/gh_mirrors/hs/HS2-HF_Patch HS2-HF_Patch是一款专为《Honey Select …...
为什么你的AI Agent像个傻子?因为你没给它装“Skill”
今年刚开年,AI Agent的热度又上来了。Cursor 让不少人觉得编程要变天,Claude Code 被捧成“最强打工人”,OpenClaw 这类开源项目更是让动手能力强的人直接开始折腾自动化。但身边真正用起来的人,最近普遍开始烦躁。让 Agent 跑个测…...
CustomTkinter:如何用Python轻松打造现代化桌面应用界面
CustomTkinter:如何用Python轻松打造现代化桌面应用界面 【免费下载链接】CustomTkinter A modern and customizable python UI-library based on Tkinter 项目地址: https://gitcode.com/gh_mirrors/cu/CustomTkinter 厌倦了传统Tkinter老旧的界面风格&…...
Linux I/O 演进史:从管道到零拷贝,一篇串起个服务端核心原语俅
前言 在使用 kubectl get $KIND -o yaml 查看 k8s 资源时,输出结果中包含大量由集群自动生成的元数据(如 managedFields、resourceVersion、uid 等)。这些信息在实际复用 yaml 清单时需要手动清理,增加了额外的工作量。 使用 kube…...
[具身智能-306]:Token详解
Token(中文定名为“词元”)是人工智能时代,特别是大语言模型(LLM)中最核心的概念之一。它不仅是模型处理信息的最小单位,更是连接算力、数据与商业价值的“通用货币”。为了让你透彻理解 Token,…...
Win11Debloat:重构Windows 11系统体验的开源优化工具
Win11Debloat:重构Windows 11系统体验的开源优化工具 【免费下载链接】Win11Debloat A simple, lightweight PowerShell script that allows you to remove pre-installed apps, disable telemetry, as well as perform various other changes to declutter and cus…...
3大突破重构教育评价:OCRAutoScore智能阅卷系统实战指南
3大突破重构教育评价:OCRAutoScore智能阅卷系统实战指南 【免费下载链接】OCRAutoScore OCR自动化阅卷项目 项目地址: https://gitcode.com/gh_mirrors/oc/OCRAutoScore OCRAutoScore是一款开源AI自动阅卷系统,通过融合OCR识别、语义分析和自动化…...
微服务为什么会走到 RPC,以及 gRPC 到底解决了什么
大多数 gRPC 文章都从 .proto、代码生成、四种调用模式开始讲,读完之后你通常知道“怎么写”,但不一定真的明白“为什么会有这套东西”。 而工程里真正棘手的,恰恰不是语法,而是当系统从单体走向微服务之后,原来那些理…...
FPGA实战:14位高速DAC的Verilog代码设计与EMC优化全解析(Vivado平台)
1. 高速DAC设计基础与核心挑战 在FPGA信号处理系统中,14位高速DAC(如AD9744)的设计往往面临两个核心矛盾:时序收敛与信号完整性。我曾在多个项目中遇到这样的场景:当DAC时钟频率超过100MHz时,输出波形会出现…...
OpenClaw浏览器自动化:gemma-3-12b-it操控Chrome完成数据采集
OpenClaw浏览器自动化:gemma-3-12b-it操控Chrome完成数据采集 1. 为什么需要AI驱动的浏览器自动化? 去年整理行业报告时,我曾连续三天手动复制粘贴上百个网页表格数据。这种重复劳动不仅效率低下,还容易出错。传统爬虫方案虽然能…...
