代理模式详解与应用

devtools/2025/1/15 18:09:29/

代理模式(Proxy Pattern),也称为委托模式或 surrogate 模式,是一种结构型设计模式。它为其他对象提供一个代理以控制对这个对象的访问。通过引入代理对象,可以在不改变原始对象接口的前提下,添加额外的功能,如权限检查、延迟加载、日志记录等。代理模式使得客户端可以通过代理间接地操作目标对象,从而实现更灵活和安全的对象交互。

代理模式的特点

  1. 增强功能:可以在不修改原始对象的情况下为其添加新的行为,例如远程调用、缓存支持、事务管理等。
  2. 控制访问:可以限制或扩展对目标对象的操作权限,确保只有授权的客户端才能执行特定的方法。
  3. 延迟初始化:对于资源密集型的对象,可以通过代理模式实现懒加载,即在第一次使用时才创建实际对象。
  4. 透明性:对于客户端来说,代理和真实主题之间的区别是透明的,它们都实现了相同的接口。

代理模式的分类

根据代理的目的和实现方式,代理模式可以分为以下几种类型:

  • 远程代理(Remote Proxy):为一个位于不同地址空间的对象提供局部代表,用于跨越网络边界进行通信。
  • 虚拟代理(Virtual Proxy):根据需要创建开销大的对象,通常用于实现延迟加载。
  • 保护代理(Protection Proxy):控制对原始对象的访问权限,允许不同的用户有不同的访问级别。
  • 智能引用(Smart Reference):除了简单的代理功能外,还可以添加额外的行为,比如计数对象的引用次数、监视对象的访问等。

代理模式的组成

  • Subject(抽象主题接口):定义了真实主题和代理类共同的接口,确保两者可以被一致地对待。
  • RealSubject(真实主题):实现了Subject接口的具体类,负责完成业务逻辑。
  • Proxy(代理类):同样实现了Subject接口,内部持有一个指向RealSubject的引用,并在其基础上添加了额外的功能。

代理模式的实现

我们将通过一个简单的例子来演示代理模式的应用:假设我们有一个在线书店系统,其中包含了一个图书库存查询服务。为了提高性能并减少数据库压力,我们可以使用代理模式来实现缓存机制,即当用户请求查看某本书的信息时,先从缓存中查找,如果不存在则去数据库中查询并将结果存入缓存。

示例代码

// 抽象主题接口 - BookService
interface BookService {String findBookInfo(String isbn);
}// 真实主题 - RealBookService
class RealBookService implements BookService {@Overridepublic String findBookInfo(String isbn) {// Simulate database query delaytry {Thread.sleep(1000); // Sleep for a second to simulate DB access time} catch (InterruptedException e) {e.printStackTrace();}return "Book Info from Database: ISBN=" + isbn;}
}// 代理类 - CachedBookService
class CachedBookService implements BookService {private final Map<String, String> cache = new HashMap<>();private final RealBookService realBookService;public CachedBookService() {this.realBookService = new RealBookService();}@Overridepublic String findBookInfo(String isbn) {if (!cache.containsKey(isbn)) {System.out.println("Cache miss, querying database...");String bookInfo = realBookService.findBookInfo(isbn);cache.put(isbn, bookInfo);} else {System.out.println("Cache hit!");}return cache.get(isbn);}
}

使用示例

public class ProxyPatternDemo {public static void main(String[] args) {BookService bookService = new CachedBookService();// 第一次查询会命中数据库System.out.println(bookService.findBookInfo("978-3-16-148410-0"));// 第二次查询会命中缓存System.out.println(bookService.findBookInfo("978-3-16-148410-0"));}
}

代理模式的应用场景

  • 当需要在不改变原有对象接口的情况下,为其添加新的功能或行为时。
  • 如果想要控制对某些敏感操作的访问权限,可以通过代理模式实现细粒度的安全控制。
  • 在处理大型对象或复杂计算时,可以使用虚拟代理来实现延迟加载,优化系统性能。
  • 对于分布式的应用程序,远程代理可以帮助隐藏底层的网络通信细节,使客户端能够像调用本地方法一样轻松地调用远程服务。

结语

希望本文能帮助您更好地理解代理模式的概念及其实际应用。如果您有任何疑问或建议,请随时留言交流。


http://www.ppmy.cn/devtools/150238.html

相关文章

ue5玩家角色添加武器。切换武器位置,手上武器放到背上。演示一下人体插槽和武器的连接。仅仅演示,实际项目不是这么用的

把第一人称资源包导进来 这就是我们枪的骨骼网格体 我们找到这个骨骼 右手添加插槽 取个名字 因为武器上也有动画&#xff0c;所有武器单独写个蓝图类 新建一个蓝图类 BP_Weapon 把枪的蓝图拖到人的静态网格体下&#xff0c;成为一个部分 选中BP_Weapon的父类套接字…

计算机网络之---网络层的基本功能

网络层简述 网络层&#xff08;Network Layer&#xff09;是OSI&#xff08;开放系统互联&#xff09;模型的第三层&#xff0c;主要负责将数据包从源主机传输到目的主机&#xff0c;处理数据传输过程中的路由选择、寻址和分段等任务。网络层的主要目的是确保数据能够从源设备准…

VSCode 插件

VSCode 插件 1. GitHub Copilot - AI 代码助手 功能&#xff1a;根据上下文提供实时代码补全&#xff0c;支持自然语言转代码&#xff0c;提供符合现代编程规范的建议。进阶技巧&#xff1a; 使用快捷键 Alt ] 切换多个建议。写注释时&#xff0c;描述业务逻辑而不是具体实现…

对话新晋 Apache SeaTunnel Committer:张圣航的开源之路与技术洞察

近日&#xff0c;张圣航被推选为 Apache SeaTunnel 的 Committer成员。带着对技术的热情和社区的责任&#xff0c;他将如何跟随 Apache SeaTunnel 社区迈向新的高度&#xff1f;让我们一起来聆听他的故事。 自我介绍 请您简单介绍一下自己&#xff0c;包括职业背景、当前的工作…

linux内存泄露定位过程(kmemleak和slab debug)

1&#xff0c;当遇到内存增加过多时&#xff0c;或者由于内存导致系统oom时我们怎么定位呢&#xff0c;定位时需要确认是内核态还是用户态内存泄露。 排查步骤 top查看VIRT和RES内存 rootubuntu2004:~# top top - 21:05:39 up 7 min, 1 user, load average: 5.01, 4.09, 2.…

3D机器视觉的类型、应用和未来趋势

3D相机正在推动机器视觉市场的增长。很多制造企业开始转向自动化3D料箱拣选&#xff0c;专注于使用3D视觉和人工智能等先进技术来简化操作并减少开支。 预计3D相机将在未来五年内推动全球机器视觉市场&#xff0c;这得益于移动机器人和机器人拣选的强劲增长。到 2028 年&#…

【机器学习:八、逻辑回归】

逻辑回归&#xff08;Logistic Regression&#xff09; 1. 逻辑回归的引出 在现实世界中&#xff0c;许多问题都涉及到分类任务。例如&#xff1a; 判断一封邮件是否为垃圾邮件&#xff1b;预测某人是否会患某种疾病&#xff1b;确定图片中是否包含某种特定物体。 这些问题…

qt 窗口(window/widget)绘制/渲染顺序 QPainter QPaintDevice Qpainter渲染 失效 无效 原因

qt窗体布局 窗体渲染过程 qt中窗体渲染逻辑顺序为 本窗体->子窗体/控件 递归&#xff0c;也就是说先渲染父窗体再渲染子窗体。其中子窗体按加入时的先后顺序进行渲染。通过下方的函数调用堆栈可以看出窗体都是在widget组件源码的widgetprivate::drawwidget中进行渲染的&am…