当前位置: 首页 > news >正文

【设计模式精讲 Day 12】代理模式(Proxy Pattern)

【设计模式精讲 Day 12】代理模式(Proxy Pattern)


文章内容

在软件开发中,代理模式是一种常见的结构型设计模式,它通过引入一个代理对象来控制对真实对象的访问。这种模式不仅能够增强系统的安全性、灵活性和可扩展性,还能在不修改原有代码的基础上实现功能增强。

作为“设计模式精讲”系列的第12天,我们将深入探讨 代理模式(Proxy Pattern) 的核心思想、实现方式、适用场景以及实际应用案例。本文面向Java开发工程师和架构师,旨在帮助读者理解如何在项目中合理使用代理模式,并提升系统的设计质量与性能。


模式定义:代理模式的核心思想

代理模式是一种结构型设计模式,它提供了一个代理对象,用于控制对另一个对象的访问。代理对象通常会封装真实对象的操作,并在调用之前或之后执行额外的逻辑,如权限校验、日志记录、延迟加载等。

核心思想:
  • 解耦:通过代理对象隔离客户端与真实对象之间的直接依赖。
  • 控制访问:允许在调用真实对象之前或之后添加额外行为。
  • 增强功能:在不修改真实对象的前提下,为对象增加新的能力。

模式结构:UML类图与关键角色说明

代理模式包含以下几个关键角色:

| 角色 | 职责 | |------|------| | Subject | 抽象接口,定义了真实对象和代理对象的公共方法。 | | RealSubject | 真实对象,实现了 Subject 接口,提供实际的功能。 | | Proxy | 代理对象,也实现了 Subject 接口,负责控制对 RealSubject 的访问。 |

UML类图描述(文字版)
  • Subject 是一个抽象接口,定义了 operation() 方法。
  • RealSubject 实现了 Subject 接口,提供具体的功能实现。
  • Proxy 同样实现了 Subject 接口,内部持有 RealSubject 的引用,并在调用 operation() 时进行额外处理。

适用场景:代理模式最适合应用的具体业务场景

| 场景 | 说明 | |------|------| | 权限控制 | 在访问资源前验证用户权限,如数据库连接、文件读写等。 | | 延迟加载 | 只有在真正需要时才初始化对象,如大文件加载、大数据查询。 | | 远程调用 | 为远程服务提供本地代理,隐藏网络细节,如RPC框架。 | | 日志与监控 | 在调用前后记录日志,用于调试或审计。 | | 安全防护 | 防止非法操作,如只读对象、只读属性等。 |


实现方式:完整的Java代码实现(带详细注释)

下面是一个基于 Java 的完整代理模式实现示例,模拟了一个简单的图像加载器,其中代理负责控制图像的加载过程。

// 1. 抽象接口:Subject
interface Image {void display();
}// 2. 真实对象:RealSubject
class RealImage implements Image {private String fileName;public RealImage(String fileName) {this.fileName = fileName;loadFromDisk();}private void loadFromDisk() {System.out.println("Loading image from disk: " + fileName);}@Overridepublic void display() {System.out.println("Displaying image: " + fileName);}
}// 3. 代理对象:Proxy
class ProxyImage implements Image {private String fileName;private RealImage realImage;public ProxyImage(String fileName) {this.fileName = fileName;}@Overridepublic void display() {if (realImage == null) {realImage = new RealImage(fileName);}realImage.display();}
}// 4. 客户端代码
public class ProxyDemo {public static void main(String[] args) {Image image1 = new ProxyImage("photo1.jpg");image1.display(); // 第一次加载,触发真实对象创建Image image2 = new ProxyImage("photo2.jpg");image2.display(); // 第二次加载,复用已有对象}
}
代码解释:
  • RealImage 是真正的图像对象,只有在构造时才会加载图像。
  • ProxyImage 是代理对象,仅在调用 display() 时才创建 RealImage 实例,实现延迟加载
  • 客户端通过 ProxyImage 访问图像,无需关心其是否已加载。

工作原理:代理模式如何解决问题的底层机制

代理模式的核心在于控制访问增强功能。当客户端调用代理对象的方法时,代理可以执行以下操作:

  1. 预处理:在调用真实对象之前,执行一些逻辑,如权限检查、参数验证。
  2. 调用真实对象:根据需求决定是否创建或复用真实对象。
  3. 后处理:在调用完成后,执行一些逻辑,如日志记录、资源释放。

通过这种方式,代理模式能够在不修改真实对象的前提下,为系统增加额外的行为,同时降低模块间的耦合度。


优缺点分析:使用该模式的优势和局限性

| 优点 | 缺点 | |------|------| | 提高系统的灵活性和可扩展性 | 增加了系统的复杂度 | | 解耦客户端与真实对象 | 代理对象可能成为性能瓶颈 | | 支持延迟加载、安全控制等功能 | 不适合所有场景,如简单对象无需代理 |


案例分析:真实项目中的代理模式应用

应用场景:Spring AOP 中的代理模式

在 Spring 框架中,AOP(面向切面编程) 就是基于代理模式实现的。Spring 使用动态代理(JDK Proxy 或 CGLIB)来为目标对象添加横切关注点(如日志、事务管理等)。

示例代码:
// 1. 定义一个接口
interface UserService {void login(String username, String password);
}// 2. 实现类
class UserServiceImpl implements UserService {@Overridepublic void login(String username, String password) {System.out.println("User " + username + " is logging in...");}
}// 3. 使用 Spring AOP 添加日志功能
@Aspect
@Component
public class LoggingAspect {@Before("execution(* com.example.service.UserService.login(..))")public void logBefore(JoinPoint joinPoint) {System.out.println("Logging before method call: " + joinPoint.getSignature().getName());}
}
工作原理:
  • Spring AOP 使用 JDK ProxyCGLIB 创建 UserService 的代理对象。
  • 当调用 login() 方法时,实际上调用的是代理对象。
  • 代理对象会在方法调用前后插入日志逻辑,从而实现无侵入式的功能增强。

与其他模式的关系:与相关设计模式的比较和组合使用方式

| 模式 | 关系 | |------|------| | 装饰器模式(Decorator Pattern) | 两者都用于增强对象功能,但装饰器模式强调动态添加功能,而代理模式更侧重于控制访问。 | | 适配器模式(Adapter Pattern) | 适配器用于兼容不同接口,而代理用于控制对对象的访问,二者目的不同。 | | 单例模式(Singleton Pattern) | 代理对象可以使用单例模式确保唯一性,尤其在远程调用中非常常见。 | | 工厂模式(Factory Pattern) | 代理对象可以通过工厂模式创建,以统一管理对象的生成过程。 |


总结:关键知识点复习与下一天内容预告

本篇详细介绍了 代理模式 的核心思想、实现方式、适用场景以及实际应用案例。我们通过 Java 代码展示了如何构建一个完整的代理模式系统,并结合 Spring AOP 案例说明了其在企业级应用中的价值。

通过代理模式,我们可以有效控制对象的访问权限、实现延迟加载、增强系统功能,同时降低模块间的耦合度。在后续的开发中,建议结合具体业务场景,灵活运用代理模式,以提升系统的可维护性和可扩展性。

下一天我们将进入行为型模式的讲解,重点介绍责任链模式(Chain of Responsibility Pattern),敬请期待!


文章标签

design-patterns,proxy-pattern,java-design-patterns,software-architecture,object-oriented-programming


文章简述

本文是“设计模式精讲”系列的第12天,围绕 代理模式(Proxy Pattern) 展开,深入解析了其核心思想、实现方式、适用场景及实际应用。文章提供了完整的 Java 代码示例,展示了如何通过代理对象控制对真实对象的访问,并结合 Spring AOP 案例说明了其在企业级开发中的重要性。此外,文章还对比了代理模式与其他设计模式的关系,并总结了其优缺点。无论是初学者还是有经验的 Java 开发者,都能从中获得实用的技术指导和设计思路。


进一步学习资料

  1. Design Patterns: Elements of Reusable Object-Oriented Software
  2. Refactoring Guru - Proxy Pattern
  3. Java Design Patterns - Proxy Pattern
  4. Spring AOP with Proxy Pattern

核心设计思想总结

本篇文章的核心设计思想是:通过代理对象控制对真实对象的访问,增强系统功能并降低耦合度。在实际项目中,当我们需要实现权限控制、延迟加载、远程调用等功能时,可以考虑使用代理模式。通过合理设计代理类,可以在不修改原有代码的前提下,为系统增加新的能力。在后续开发中,建议结合具体业务场景,灵活运用代理模式,以提升系统的可维护性和可扩展性。

http://www.lryc.cn/news/574071.html

相关文章:

  • WebSocket 进阶全攻略:心跳机制、断线重连、socket.io、鉴权与WSS配置
  • LeetCode热题100—— 160. 相交链表
  • 拼多多API限流机制破解:分布式IP池搭建与流量伪装方案
  • Re:从零开始的地址映射基本分页存储管理方式(考研向)
  • 京东金融API支付链路剖析:白条分期接口的安全加固方案
  • ​​FFmpeg命令全解析:三步完成视频合并、精准裁剪​​、英伟达显卡加速
  • 飞往大厂梦之算法提升-7
  • vue | vue-macros 插件升级以及配置
  • OSC靶机练习 PG ZenPhoto
  • 华为HN8145V光猫改华为蓝色公版界面,三网通用,xgpon公版光猫
  • redis如何使用IO多路复用
  • 深入理解PHP中的面向对象编程
  • 医疗B端系统布局创新:医护操作界面与患者数据的差异化呈现
  • 347. 前 K 个高频元素
  • 洛谷P1217 [USACO1.5] 回文质数 Prime Palindromes
  • Rust 切片类型(slice type)
  • 关于华为Pura70Pro+升级鸿蒙NEXT和回退
  • 第三章---需求分析
  • JavaScript 中 async/await 的工作原理
  • Chromium 136 编译指南 macOS篇:编译优化技巧(六)
  • 【C++】C++中的虚函数和多态的定义与使用
  • 微软ASR与开源模型分析
  • 黑马python(十五)
  • C语言数组介绍 -- 一维数组和二维数组的创建、初始化、下标、遍历、存储,C99 变长数组
  • 三、kubectl使用详解
  • 安卓9.0系统修改定制化____如何编辑和修改安卓手机默认按键配置文件 改变按键功能 操作篇 九
  • LeetCode中K个链表的链接的解法
  • 区块链大讲堂 | 分布式隐私计算友好的零知识证明协议
  • 矩阵阶数(线性代数) vs. 张量维度(深度学习):线性代数与深度学习的基石辨析,再也不会被矩阵阶数给混淆了
  • Flink SQL执行流程深度剖析:从SQL语句到分布式执行