23种设计模式-结构型模式-代理
文章目录
- 简介
- 问题
- 解决方案
- 代码
- 核心设计要点
- 总结
简介
代理是一种结构型设计模式,让你能够提供对象的替代品或其占位符。代理控制着对于原对象的访问,并允许在把请求提交给对象前后进行一些处理。
问题
为什么要控制对于某个对象的访问呢?举个例子:有一个消耗大量系统资源的巨型对象,你只是偶尔需要使用它。

如上图,数据库连接的初始化和查询可能会非常缓慢,我们可以先实现延迟初始化,只在实际有需要时再创建这个对象。这样对象的所有客户端都要执行延迟初始代码。这很可能会带来很多重复代码。在理想情况下,我们希望把延迟初始化的代码直接放入这个对象的类里,但这并不一定能实现, 因为这个类可能是第三方封闭库的一部分。
解决方案
代理模式建议 新建一个和原来的服务对象接口相同的代理类,然后把代理对象传递给所有原始对象客户端。代理类接收到客户端请求后会创建实际的服务对象,并把所有工作委派给它。

如上图,代理把自己伪装成数据库对象,可以在客户端或实际数据库对象不知情的情况下处理延迟初始化和缓存查询结果的工作。
这有什么好处呢?如果需要在类的主要业务逻辑前后执行一些工作,你不需要修改原始类就能完成这个工作。而且由于代理实现的接口与原类相同,因此你可以在任何一个使用实际服务对象的客户端中使用它。
代码
// 服务接口
interface Database {String executeQuery(String sql);
}// 真实服务对象
class RealDatabase implements Database {public RealDatabase() {initializeConnection(); // 耗时的连接初始化}private void initializeConnection() {System.out.println("正在建立数据库连接...");}@Overridepublic String executeQuery(String sql) {System.out.println("执行真实查询: " + sql);return "结果数据"; // 示例返回值}
}// 代理类(延迟加载和缓存)
class DatabaseProxy implements Database {private RealDatabase realDatabase; private Map<String, String> cache = new HashMap<>(); // 查询结果缓存@Overridepublic String executeQuery(String sql) {// 延迟初始化(虚拟代理模式)if (realDatabase == null) {realDatabase = new RealDatabase(); }// 结果缓存逻辑(缓存代理)if (cache.containsKey(sql)) {System.out.println("[Proxy] 返回缓存结果: " + sql);return cache.get(sql);}String result = realDatabase.executeQuery(sql);cache.put(sql, result);return result;}
}// 客户端交互
class Application {public static void main(String[] args) {Database proxy = new DatabaseProxy();// 第一次查询触发真实连接System.out.println(proxy.executeQuery("SELECT * FROM users"));// 重复查询使用缓存System.out.println(proxy.executeQuery("SELECT * FROM users"));// 新查询继续代理System.out.println(proxy.executeQuery("SELECT COUNT(*) FROM products"));}
}
核心设计要点
- 代理类与现实服务实现相同接口
- 第一次查询延迟初始化真实连接(虚拟代理模式)
- 哈希表缓存重复查询结果(缓存优化)
- 客户端代码不需感知代理存在(透明访问)
总结

- 服务接口(Service Interface):声明接口,代理必须遵循这个接口才能伪装成服务对象。
- 服务(Service)类提供了一些实用的业务逻辑。
- 代理(Proxy)类包含一个指向服务对象的引用成员变量。代理完成他的任务之后,(比如延迟初始化、记录日志、访问控制和缓存等),会把请求传递给服务对象。通常情况下,代理会对这个服务对象的整个生命周期进行管理。
- 客户端(Client)能通过同一接口跟服务或代理进行交互,所以你可在一切需要服务对象的代码中使用代理。
相关文章:
23种设计模式-结构型模式-代理
文章目录 简介问题解决方案代码核心设计要点 总结 简介 代理是一种结构型设计模式,让你能够提供对象的替代品或其占位符。代理控制着对于原对象的访问,并允许在把请求提交给对象前后进行一些处理。 问题 为什么要控制对于某个对象的访问呢?…...
Windows C++ 排查死锁
开发出来应用程序突然间卡死不动,如果其中是因为死锁问题卡列该如何排查 下面是一个简单的死锁例子 #include <iostream> #include <thread> #include <mutex>std::mutex a, b;void function_a() {std::lock_guard<std::mutex> _x(a);std:…...
ctfshow
1,web517 通过输入两个单引号让查询语句正常,判断是什么注入,使用的是什么字符 然后我们通过order by 判断回显位,进行一个联合查询注入 获取数据库名 ctfshow的sqli-labs和本地搭建最大的不同,就是show的flag不在当前…...
【AI论文】什么、如何、何处以及效果如何?大语言模型测试时缩放技术调研
摘要:随着预训练时代对计算(数据和参数)缩放的热情逐渐减退,测试时缩放(Test-Time Scaling, TTS),也被称作“测试时计算”,已成为一个备受瞩目的研究焦点。近期研究表明,…...
大模型学习一:deepseek api 调用实战以及参数介绍
一、说明 DeepSeek(杭州深度求索人工智能基础技术研究有限公司)是一家专注于大语言模型(LLM)研发的中国创新型科技公司,成立于2023年7月17日,由幻方量化孵化。其核心产品包括开源推理模型DeepSeek-R1、多模…...
C++ 编程指南33 - 使用模板来表达适用于多种参数类型的算法
一:概述 在 C 中,模板(Templates)提供了一种强大的泛型编程方式,使代码可以适用于不同的数据类型,而无需重复编写类似的逻辑。模板的主要目标是: 泛化能力(Generality)&a…...
MYSQL实现获取某个经纬度区域内的数据
1.创建表 2.插入表数据 INSERT INTO tf_sys.tf_location(name, longitude, latitude, location) VALUES (资料名称1, 114.437625, 16.016914, ST_GeomFromText(POINT(114.437625 16.016914))); INSERT INTO tf_sys.tf_location(name, longitude, latitude, location) VALUES (…...
《Python实战进阶》No39:模型部署——TensorFlow Serving 与 ONNX
第39集:模型部署——TensorFlow Serving 与 ONNX 摘要 在机器学习项目中,训练好的模型需要被部署到生产环境中才能发挥实际价值。本集聚焦于如何将模型高效地部署到生产环境,涵盖TensorFlow Serving和ONNX两种主流工具的使用方法。我们将从理…...
嵌入式调试进阶:从手动到自动的HardFault破案指南
今天和大家聊聊嵌入式开发中让无数新手头疼,但又避不开的HardFault。 还记得我刚入行那会儿,信誓旦旦改了几行代码,信心爆棚地烧录进板子。结果呢?灯!没!亮!调试器显示程序卡在了HardFault_Han…...
YOLOv11区域检测
TrackZone 使用Ultralytics YOLO11 -Ultralytics YOLO 文档 如何通过Ultralytics YOLO11 在Python 中使用 TrackZone? 只需几行代码,您就可以在特定区域设置对象跟踪,从而轻松将其集成到您的项目中。 import cv2from ultralytics import s…...
手工win提权土豆家族一键梭哈
手工提权 就是在没有工具使用的时候进行提权(或者是win版本过新导致的exp作者没更新等) 优点就是 随选随用 缺点就是非常繁琐(建议是先土豆梭哈然后再手工提权) 先进行信息收集(这边靶机以例子) 这个…...
在Qt中直接在构建目录下直接运行.exe文件报错问题分析
在Qt中直接在构建目录下直接运行.exe文件报错问题分析 在学习Qt的过程中遇到过一个问题,直接在Qt构建目录下运行生成的.exe文件时会报错。这和MFC有一定的差别,如果MFC是可以直接运行的。 这是怎么回事呢? 在 Qt 中直接运行构建目录下的 .…...
头戴式面捕头盔:高精度捕捉真人面部表情,赋能元宇宙多场景应用
随着元宇宙虚拟人与现实场景的不断交融,如何赋予虚拟人更加自然,灵动的表情成为了业内人员共同讨论的话题,尤其是在虚拟人直播,影视动画制作方面。在虚拟人直播间,丰富的面部表情可以赋予虚拟人更加生动的情感表达&…...
LLM大模型教程——什么是AI大模型
引言 当GPT-4展现出惊人的上下文理解能力,当Stable Diffusion创造出媲美人类画师的图像作品,当AlphaFold2破解蛋白质折叠密码——这些里程碑事件标志着人工智能发展进入大模型主导的新纪元。本综述将深入解析这一技术革命的核心载体——AI大模型。 一、AI 大模型是什么 概…...
产品经理的大语言模型课 04 -模型应用的云、边、端模式对比
目录 算力部署方式的影响因素数据量计算难度前期投入数据隐私应用规模与泛化能力 云、边、端部署的特点和对比典型场景举例社区人脸门禁后厨老鼠识别 未来展望 算力部署方式的影响因素 最近和人工智能从业者进行了非常广泛的沟通,尝试对模型应用的云、边、端模式进…...
机器学习(八):K-Means聚类原理与实战
声明:未经允许禁止转载与抄袭。 前言 k k k均值( k k k-means)聚类算法是一种经典的无监督聚类算法,本文将深入解析其理论原理,并在真是数据集上进行算法实践,话不多说,请看下文。 算法原理 …...
基于yolo11的BGA图像目标检测
1.产生图像数据的分辨率 2.产生图像的大小 3.产生图像是黑白或是RGB彩色 灰度图像,达到识别要求,减少计算量 4.标注数据的精准程度 1.模型标注后,少量标注全部人工校验,大量数据抽检,部分人工检验 2.明确边界框贴合…...
分享一些新版GPT-4o使用方式!能多模态生图!
目前GPT-4o的整体测评,真的很惊艳。 不知道又有多少人因为OpenAI的这次更新而失业,当然只要AI用得好,会有更多人因之而受益!很多人表示不知道怎么用,对于门外汉来说,4o似乎有点高端。 今天就给大家介绍几…...
【stm32--HAL库DMA+USART+空闲中断不定长收发数据】
串口通信-Hal库实现不定长度收发,DMAUSART DMA串口STM32CUBEMX配置(工程创建)基础配置时钟配置工程配置 代码编写现象 DMA 在正式配置之前,我们先来一起简单了解一下DMA。DMA(Direct Memory Access,直接内…...
【算法中的数学】欧拉筛埃氏筛
筛质数 题目传送门 题目链接 一、题目描述 给定一个正整数 n,请你求出 1∼n 中质数的个数。 输入格式 共一行,包含整数 n。 输出格式 共一行,包含一个整数,表示 1∼n 中质数的个数。 数据范围 1 ≤ n ≤ 10⁶ 输入样例&am…...
【SPP】蓝牙串口配置中LM互操作性要求深度解析
在蓝牙协议栈中,链路管理器(Link Manager, LM)承担着链路建立、安全管理、功耗控制等核心功能。对于串行端口配置文件(SPP)而言,LM 的互操作性直接影响连接稳定性、数据安全性和设备功耗。本文基于蓝牙核心…...
Java迭代器【设计模式之迭代器模式】
目录 一.前言 二.正文 1.我写的类为什么不能使用增强for(迭代器遍历) 2.代码健全性——迭代器常见的两个Exception 1.NoSuchElementException 2.ConcurrentModificationException 三.后言 一.前言 本篇面向对象主要为和我一样的小白,主要是对迭代器模式的浅…...
Eclipse IDE
创建新的Java项目和类 在 Eclipse IDE 中创建一个新的 Java 项目和 Java 类的步骤如下: 1. 创建新的 Java 项目 打开 Eclipse IDE。在菜单栏中,点击 File > New > Java Project。在弹出的对话框中,输入项目名称(例如&…...
【面试篇】多线程
基础概念 线程的生命周期有哪些状态?它们是如何转换的? 答案:线程的生命周期有以下六种状态: 新建(New):线程被创建但尚未启动,此时线程对象已被分配内存空间,相关属性已…...
MySQL表缺乏主键或唯一索引对主从复制的深度影响及解决方案
引言 在MySQL数据库设计中,主键(Primary Key)和唯一索引(Unique Index)不仅是数据完整性的基石,更是主从复制(Replication)可靠性的关键。然而,许多开发者或DBA因历史遗…...
计算机视觉算法实战——基于YOLOv8的自动驾驶障碍物实时感知系统
✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连✨ 引言:自动驾驶感知系统的关键挑战 自动驾驶技术正以前所未有的速度重塑交通出行方式ÿ…...
【boost搜索引擎】下
boost搜索引擎 1. 编写搜索引擎模块 Searcher2. 编写 http_server 模块3. 编写前端模块4. 添加日志5. 补充 去掉暂停词6. 项目扩展方向 1. 编写搜索引擎模块 Searcher 这一模块主要提供建立索引,以及收到用户的发起的http请求通过Get方法提交的搜索关键字ÿ…...
数据结构优化DP总结
单调栈:Codeforces Round 622 (Div. 2) C2. Skyscrapers (hard version) 简单来讲就是最后需要呈现出一个单峰数组,使得总高度最高。 最开始想到暴力枚举每一个元素都充当最高的“单峰”,但是这里的 n 过大,这样枚举肯定会TLE。 …...
[Linux系统编程]进程间通信—system V
进程间通信—system V 1. System V 共享内存(Shared Memory)1.1 共享内存的建立过程1.2 共享内存函数2. System V 消息队列(Message Queues)3. System V 信号量(Semaphores)4. 总结前言: 之前所提的管道通信是基于文件的,OS没有做过多的设计工作。 system V 进程间通信…...
Eigen库几何模块深度解析与实践指南
Eigen库几何模块深度解析与实践指南 a. Eigen几何模块概述 i. 几何模块的核心功能 在三维空间中,几何变换是描述物体位置和姿态变化的基础,其数学基础涵盖了线性代数中的矩阵运算等知识。Eigen库的几何模块为这些变换提供了高效且便捷的实现方式。 旋转、平移和缩放是三维…...
