GoF设计模式——代理模式
为什么需要代理模式有时候我们不能或不想直接访问某个对象。比如对象创建开销很大需要延迟加载或者需要在访问前做权限检查或者需要记录访问日志。直接在业务代码中掺杂这些逻辑会让代码臃肿且难以维护。代理模式通过引入一个中间层将这些控制逻辑从业务代码中分离出来。客户端代码不需要知道它是在和代理交互还是真实对象交互两者可以透明替换。概念代理模式Proxy Pattern是一种结构型设计模式核心思想是为一个对象提供一个替身代理以控制对这个对象的访问。代理对象和真实对象实现相同的接口客户端通过代理间接访问真实对象代理可以在调用前后添加额外的控制逻辑。代理模式的主要角色有Subject抽象主题声明真实主题和代理共同实现的业务方法客户端面向该接口编程RealSubject真实主题定义代理所代表的真实对象是客户端最终要访问的对象Proxy代理持有对真实主题的引用实现与真实主题相同的接口在调用真实主题前后添加控制逻辑类图展示了静态结构但对代理模式这种调用拦截的场景时序图更能体现动态调用流程RealSubjectProxyClientRealSubjectProxyClientrequest()前置处理权限/日志/延迟加载request()返回结果后置处理日志/缓存返回结果可以把代理理解为私人助理老板客户端有事找某人真实对象先通过助理代理。助理可以在前面挡掉不重要的打扰权限控制也可以在事后记录行程日志老板全程不需要直接接触对方。这个比喻贯穿后面的实现章节方便对照理解。实现代理模式的基本实现分为以下几个步骤定义抽象主题一般是接口或抽象类声明真实主题和代理对象实现的业务方法定义真实主题实现抽象主题中的具体业务定义代理类包含对RealSubject的引用提供和真实主题相同的接口在调用前后添加控制逻辑客户端使用代理// 抽象主题 interface Subject { // 声明同业务对象同名的方法 public void request(); } // 真实主题 class RealSubject implements Subject { public void request() { System.out.println(RealSubject request); } } // 代理类 class Proxy implements Subject { private RealSubject realSubject; Override public void request() { // 访问真实主题之前延迟加载 if (realSubject null) { realSubject new RealSubject(); } // 调用真实主题的方法 realSubject.request(); // 访问真实主题之后可添加日志等逻辑 } }总结代理模式本质上是一层中间人——为真实对象提供一个替身在调用前后添加控制逻辑。什么时候用想控制对某个对象的访问权限、延迟加载、缓存、日志需要为远程对象提供本地代表引入第三方库或遗留代码需要统一调用方式什么时候不用接口差异巨大代理会变得臃肿能修改真实对象源码且代价不大直接修改更简单系统设计阶段就能定义接口规范从源头统一即可简单记忆代理解决控制访问的问题是给真实对象加一层控制。能改源码就改改不了才用代理。代理 vs 装饰器 vs 适配器 vs 外观四个结构型模式都包了一层对象结构相似但意图不同模式接口关系核心意图代理目标接口 被包装对象接口控制访问附加访问前后逻辑装饰器目标接口 被包装对象接口增强功能接口不变适配器目标接口 ≠ 被包装对象接口转换接口让不兼容的类协同外观目标接口是新设计的简化复杂子系统的调用口诀对比代理控访问装饰增功能适配改接口外观简调用。代理模式 vs 中介者模式两者都引入中间层结构相似但意图完全不同维度代理模式中介者模式核心意图控制对单个对象的访问协调多个对象之间的交互对象关系客户端 → 代理 → 真实对象单向委托多个同事对象 ↔ 中介者 ↔ 多个同事对象多向协调封装内容访问控制逻辑权限、延迟加载、缓存对象间的交互规则、通信协议客户端感知客户端不知道真实对象存在各同事对象知道中介者存在但不直接知道其他同事应用场景Spring AOP、MyBatis Mapper、远程调用MVC 框架的 Controller、聊天室服务器、GUI 事件分发用例子说明代理模式你要见 CEO先通过秘书代理。秘书控制访问——过滤不重要的人、安排时间。你只和秘书打交道CEO 对你透明。中介者模式公司的各部门销售、研发、财务不直接相互沟通所有协调通过行政部中介者。销售要研发资源找行政部安排财务要销售数据找行政部转发。各部门知道行政部但不直接依赖其他部门。简单记忆代理管谁能动中介者管怎么联动。代理是单对象的门禁中介者是多对象的调度中心。常见误区误区代理模式 装饰器模式 → 意图不同一个控访问一个增功能误区代理必须和真实对象同接口 → 对这是代理的基本要求否则就不是代理了误区SpringTransactional在同一个类内部调用不生效 → 这是自调用绕过代理的经典坑AOP 代理需要外部调用才能触发拦截逻辑练习题目门禁系统权限控制题目描述某科技园区的门禁系统管理着多个房间每个房间有名称和最低访问权限等级。用户通过门禁终端访问房间门禁终端作为代理会检查用户的权限等级用户权限 ≥ 房间要求的等级 → 放行房间显示欢迎信息用户权限 房间要求的等级 → 拒绝房间不会响应请使用代理模式实现该门禁系统。其中Room真实对象拥有 enter() 方法输出欢迎信息RoomProxy代理在调用 enter() 前进行权限检查只有通过才委托给真实对象输入描述第一行输入一个整数表示用户的权限等级。第二行输入一个整数 N1 ≤ N ≤ 20表示要访问的房间数量。接下来 N 行每行包含房间名称和该房间要求的最低权限等级用空格分隔。输出描述对每个房间通过代理访问后输出权限足够欢迎进入[房间名]权限不足权限不足无法进入[房间名]输入示例2 3 MeetingRoom 1 Lab 3 Office 2输出示例欢迎进入MeetingRoom 权限不足无法进入Lab 欢迎进入Office解题思路代理类RoomProxy实现Room接口内部持有用户权限。在enter()方法中先检查用户权限是否满足房间要求满足则委托给RealRoom.enter()否则直接拒绝。这体现了代理模式的核心——代理在调用真实对象之前增加控制逻辑权限校验对客户端透明。import java.util.*; public class Main { public static void main(String[] args) { Scanner sc new Scanner(System.in); int qx sc.nextInt(); int n sc.nextInt(); RoomProxy proxy new RoomProxy(qx); while (n-- 0) { String name sc.next(); int roomQx sc.nextInt(); RealRoom room new RealRoom(name, roomQx); proxy.setRoom(room); proxy.enter(); } } } interface Room { public void enter(); } class RealRoom implements Room { private String name; private int qx; public RealRoom(String name, int qx) { this.name name; this.qx qx; } public void enter() { System.out.println(欢迎进入 this.name); } public String getName() { return this.name; } public int getQx() { return this.qx; } } class RoomProxy implements Room { private int qx; private RealRoom room; public RoomProxy(int qx) { this.qx qx; } public void setRoom(RealRoom room) { this.room room; } public void enter() { if (this.qx room.getQx()) { room.enter(); } else { System.out.println(权限不足无法进入 room.getName()); } } }扩展实际项目中的代理模式Spring AOP 的动态代理Spring AOP 是代理模式最经典的应用。当 Bean 被 AOP 增强时Spring 不会返回原始对象而是返回一个代理对象。代理在方法调用前后插入切面逻辑事务、日志、权限校验等对调用方完全透明。// 业务代码完全感知不到代理的存在 Service public class OrderService { Transactional // 事务由代理自动管理 public void createOrder(Order order) { orderDao.save(order); inventoryService.deduct(order.getProductId(), order.getQty()); } } // Spring 内部创建代理对象JDK 动态代理或 CGLIB // 代理在 createOrder 前后自动开启/提交/回滚事务关键点Spring 默认对实现了接口的 Bean 使用 JDK 动态代理对没有实现接口的 Bean 使用 CGLIB 代理。开发者只需写Transactional、Cacheable等注解代理负责增强逻辑的织入。JDK 动态代理 vs CGLIB 对比

相关新闻

搬瓦工 KiwiVM 面板免费 AI 助手 Amy 功能演示 | 告别繁琐的命令行

搬瓦工 KiwiVM 面板免费 AI 助手 Amy 功能演示 | 告别繁琐的命令行

本文首发于只抄博客,欢迎点击原文链接了解更多内容。 介绍 Amy 是搬瓦工在 2025 年 1 月推出的内置 AI 助手,向所有套餐免费开放。彼时的 Amy 还只是个对接了 KiwiVM 控制面板的 “问答型” AI,只能提供简单的对话以及操作建议。 在 2026 年 5 月,Amy 迎来了全面升级,不…

2026/6/23 11:54:04阅读更多 →
蚂蚁面试官:“你的 Agent 怎么触发记忆提取?“ 我不屑:“每轮结束触发一次呗。“ 他冷笑:“那 Claude Code 为什么不这么设计?“ 我:……

蚂蚁面试官:“你的 Agent 怎么触发记忆提取?“ 我不屑:“每轮结束触发一次呗。“ 他冷笑:“那 Claude Code 为什么不这么设计?“ 我:……

学员最近面蚂蚁,聊到他做的 Agent 项目,面试官就问了这个: “你的 Agent 是每轮对话结束都往记忆里写吗?” 他说:“对,每轮结束后触发一次提取。” 面试官冷笑了一下:“每轮都触发&#xff0…

2026/6/23 11:54:04阅读更多 →
随机过程WebApp实验室:从随机动力学到 AI 洞察的概率世界

随机过程WebApp实验室:从随机动力学到 AI 洞察的概率世界

为什么随机过程才是现代概率论真正的核心?概率论更多关注静态随机事件,例如一次抽样、一次投掷或某个随机变量的分布性质。但现实世界中的大量系统,却始终处于持续演化之中。金融市场价格的涨跌、粒子的扩散运动、网络流量的波动、用户行为的…

2026/6/23 11:54:04阅读更多 →
深度解析Arduino-ESP32中的ESP32-C2隐藏开发板配置

深度解析Arduino-ESP32中的ESP32-C2隐藏开发板配置

深度解析Arduino-ESP32中的ESP32-C2隐藏开发板配置 【免费下载链接】arduino-esp32 Arduino core for the ESP32 family of SoCs 项目地址: https://gitcode.com/GitHub_Trending/ar/arduino-esp32 Arduino-ESP32项目为ESP32系列芯片提供了完整的Arduino开发环境支持&am…

2026/6/23 13:09:16阅读更多 →
ReadCat开源小说阅读器:纯净阅读体验的终极指南

ReadCat开源小说阅读器:纯净阅读体验的终极指南

ReadCat开源小说阅读器:纯净阅读体验的终极指南 【免费下载链接】read-cat 一款免费、开源、简洁、纯净、无广告的小说阅读器 项目地址: https://gitcode.com/gh_mirrors/re/read-cat 厌倦了广告弹窗的干扰?受够了隐私泄露的担忧?想要…

2026/6/23 13:09:16阅读更多 →
一键下载B站视频:BilibiliDown跨平台下载工具完全指南

一键下载B站视频:BilibiliDown跨平台下载工具完全指南

一键下载B站视频:BilibiliDown跨平台下载工具完全指南 【免费下载链接】BilibiliDown (GUI-多平台支持) B站 哔哩哔哩 视频下载器。支持稍后再看、收藏夹、UP主视频批量下载|Bilibili Video Downloader 😳 项目地址: https://gitcode.com/gh_mirrors/b…

2026/6/23 13:09:16阅读更多 →
一键恢复:在DSM 7.2.2/7.3.x上重新启用Video Station完整功能

一键恢复:在DSM 7.2.2/7.3.x上重新启用Video Station完整功能

一键恢复:在DSM 7.2.2/7.3.x上重新启用Video Station完整功能 【免费下载链接】Video_Station_for_DSM_722 Script to install Video Station in DSM 7.2.2 and DSM 7.3 项目地址: https://gitcode.com/gh_mirrors/vi/Video_Station_for_DSM_722 核心关键词&…

2026/6/23 13:09:16阅读更多 →
如何在Windows电脑上免费实现AirPlay投屏:终极开源方案指南

如何在Windows电脑上免费实现AirPlay投屏:终极开源方案指南

如何在Windows电脑上免费实现AirPlay投屏:终极开源方案指南 【免费下载链接】airplay2-win Airplay2 for windows 项目地址: https://gitcode.com/gh_mirrors/ai/airplay2-win 想要将iPhone或iPad屏幕无线投射到Windows电脑上吗?AirPlay2-Win为您…

2026/6/23 13:09:16阅读更多 →
如何快速掌握猫抓插件:浏览器资源嗅探的终极指南

如何快速掌握猫抓插件:浏览器资源嗅探的终极指南

如何快速掌握猫抓插件:浏览器资源嗅探的终极指南 【免费下载链接】cat-catch 猫抓 浏览器资源嗅探扩展 / cat-catch Browser Resource Sniffing Extension 项目地址: https://gitcode.com/GitHub_Trending/ca/cat-catch 你是不是经常遇到这样的情况&#xff…

2026/6/23 13:04:16阅读更多 →
【人工智能】一文搞定到底什么是智能体

【人工智能】一文搞定到底什么是智能体

【人工智能】一文搞定到底什么是智能体 一文搞定到底什么是智能体【人工智能】一文搞定到底什么是智能体一. LM,WorkFlow,Agent分别有什么么不同二. Agent的思考过程是怎样的三. Agent的五个核心部分1)LLM2)Prompt3)Me…

2026/6/23 7:04:52阅读更多 →
嵌入式GUI控件实战:ROTARY、SCROLLBAR、SLIDER原理与应用

嵌入式GUI控件实战:ROTARY、SCROLLBAR、SLIDER原理与应用

1. 嵌入式GUI控件:从原理到实战的深度解析在嵌入式系统开发中,图形用户界面(GUI)的设计与实现往往是项目从“能用”到“好用”的关键一跃。不同于资源充沛的PC或移动平台,嵌入式设备的GUI需要在有限的CPU性能、内存空间…

2026/6/23 1:55:32阅读更多 →
Google AI Studio 300美元额度的真相与实战指南

Google AI Studio 300美元额度的真相与实战指南

1. 这300美金不是“送钱”,而是Google埋下的第一道技术门槛 你看到标题里那个醒目的“$300美金”时,第一反应可能是:又一个免费额度?领完就完事?我亲手试过——这300美金根本不是红包,而是一张入场券&…

2026/6/23 5:55:37阅读更多 →
2026年京东云 618 活动 Hermes Agent/OpenClaw配置Token Plan新手必看指南

2026年京东云 618 活动 Hermes Agent/OpenClaw配置Token Plan新手必看指南

2026年京东云 618 活动 Hermes Agent/OpenClaw配置Token Plan新手必看指南。OpenClaw是开源的个人AI助手,Hermes Agent则是一个能自我进化的AI智能体框架。阿里云提供计算巢、轻量服务器及无影云电脑三种部署OpenClaw 与 Hermes Agent的方案、百炼Token Plan兼容主流…

2026/6/23 0:00:38阅读更多 →
2026年北京电子沙盘制作公司深度评测:从技术选型到落地效果,谁在真正定义“数字+实体”的融合边界?

2026年北京电子沙盘制作公司深度评测:从技术选型到落地效果,谁在真正定义“数字+实体”的融合边界?

模块一:行业背景——百亿赛道爆发,北京市场的特殊性与选型困局2026年,电子沙盘行业已走过“要不要做”的讨论,进入“找谁做、怎么做”的深水区。据行业研究机构数据,2025年国内电子沙盘市场规模已突破85亿元&#xff0…

2026/6/23 0:00:38阅读更多 →
音视频场景下的 Java 开发者面试:技术与挑战

音视频场景下的 Java 开发者面试:技术与挑战

面试互联网大厂:从音视频场景看 Java 开发者的技能与挑战 在互联网大厂求职的面试中,Java 开发者往往需要面对严苛的技术问题。今天,我们将通过一位名叫燕双非的搞笑程序员与严肃的面试官之间的对话,看看在音视频场景下&#xff0…

2026/6/23 0:00:38阅读更多 →