设计模式教程:代理模式(Proxy Pattern)

代理模式(Proxy Pattern)是一种结构型设计模式,它通过创建一个代理对象来控制对另一个对象的访问。代理对象充当真实对象的替代者,并且可以在访问真实对象之前或者之后执行额外的操作。代理模式常用于延迟加载、权限控制、远程代理、缓存等场景。

1. 代理模式的定义

代理模式 通过引入代理对象来控制对某个对象的访问。代理对象和真实对象实现相同的接口,客户端对代理对象的操作就像是对真实对象的操作一样,但代理对象可以在操作前或操作后做一些额外的处理。

代理模式通常用于以下几种场景:

  • 远程代理:表示一个对象在不同的地址空间(通常是网络)上的代理。
  • 虚拟代理:用于延迟初始化的场景,只有在需要时才创建对象。
  • 保护代理:控制对对象的访问权限,做权限检查。
  • 缓存代理:缓存某个对象的状态,避免重复计算。

2. 代理模式的角色

代理模式主要涉及以下几个角色:

  • Subject(抽象主题角色):定义了真实对象和代理对象的公共接口,通常是一个接口或抽象类。真实对象和代理对象都要实现这个接口。

  • RealSubject(真实主题角色):实现了 Subject 接口,定义了代理所代表的真实对象的具体业务逻辑。

  • Proxy(代理角色):代理对象也实现了 Subject 接口,内部持有对真实对象的引用。代理对象可以在调用真实对象方法之前或之后执行一些额外操作。

3. 代理模式的种类

根据代理的使用场景,代理模式可以分为以下几种类型:

1) 虚拟代理(Virtual Proxy)

虚拟代理用于延迟加载对象。它会在客户端首次请求真实对象时才创建真实对象实例,并返回给客户端。虚拟代理通常用于大对象、资源消耗大的对象的加载。

2) 远程代理(Remote Proxy)

远程代理用于对象位于不同地址空间的情况(如跨网络访问)。它代表一个远程对象,通过代理对象来实现对远程对象的访问。常见的应用场景是分布式系统中的远程调用(如 RMI)。

3) 保护代理(Protection Proxy)

保护代理控制对某个对象的访问权限。它通常会在客户端访问真实对象之前,进行权限验证、日志记录等操作,确保只有合法的操作才会传递到真实对象。

4) 缓存代理(Cache Proxy)

缓存代理用于缓存真实对象的计算结果,避免重复的计算。当请求真实对象时,代理对象先检查缓存,如果存在则直接返回缓存中的结果;如果不存在,则请求真实对象并将结果缓存。

5) 智能代理(Smart Proxy)

智能代理对真实对象的访问进行了额外的处理,通常用来实现一些辅助功能,如计数、对象生命周期管理等。

4. 代理模式的结构图

 +---------------------+|       Subject       |<-----------------------++---------------------+                        || + request()         |                        |+---------------------+                        |^                                     ||                                     |+------------------------+                   ||   RealSubject          |                   |+------------------------+                   || + request()            |                   |+------------------------+                   |^                                     ||                                     |+------------------------+                   || Proxy                  |-------------------++------------------------+| + request()            |+------------------------+

5. 代理模式的实现

代码示例:代理模式用于控制访问权限

假设我们有一个 RealSubject 类,它表示一个资源管理对象。我们希望控制对该资源的访问,只有合法用户才能访问资源。为此,我们可以使用代理模式,通过一个代理类来控制访问。

代码实现:
// 主题接口(Subject)
interface Subject {void request();
}// 真实主题类(RealSubject)
class RealSubject implements Subject {@Overridepublic void request() {System.out.println("RealSubject: Handling request");}
}// 代理类(Proxy)
class Proxy implements Subject {private RealSubject realSubject;private String userRole;public Proxy(String userRole) {this.userRole = userRole;}@Overridepublic void request() {if (checkAccess()) {if (realSubject == null) {realSubject = new RealSubject();  // 延迟加载}realSubject.request();  // 代理请求转发给真实主题对象} else {System.out.println("Proxy: Access denied.");}}// 检查用户权限private boolean checkAccess() {if ("admin".equals(userRole)) {System.out.println("Proxy: Access granted.");return true;} else {System.out.println("Proxy: Access denied.");return false;}}
}public class ProxyPatternExample {public static void main(String[] args) {// 创建代理对象并检查访问权限Subject proxy = new Proxy("admin");  // 用户为 admin,访问权限允许proxy.request();System.out.println();Subject proxy2 = new Proxy("user");  // 用户为普通用户,访问权限被拒绝proxy2.request();}
}
代码解析:
  1. Subject:定义了 request() 方法,RealSubjectProxy 都实现了该接口。
  2. RealSubject:实现了 Subject 接口的具体业务逻辑,执行实际的请求处理。
  3. Proxy:是代理类,它控制对 RealSubject 的访问,首先检查是否具有访问权限(在本例中是通过 userRole 字段来判断),如果允许访问,则代理请求转发给 RealSubject;否则拒绝访问。
  4. 检查访问权限Proxy 类中的 checkAccess() 方法根据用户角色来判断是否允许访问。如果角色是 admin,则允许访问;否则拒绝访问。
输出:
Proxy: Access granted.
RealSubject: Handling requestProxy: Access denied.

在这个例子中,代理模式通过 Proxy 类来控制访问,只有用户角色为 admin 时才能访问 RealSubject。这种方式实现了对真实对象的访问控制和延迟加载。

6. 代理模式的应用场景

代理模式可以应用于以下场景:

  1. 延迟加载(虚拟代理): 当对象的创建开销非常大,且客户端并不总是需要该对象时,可以使用虚拟代理延迟创建该对象。只有在客户端真正需要时,才创建真实对象。

  2. 权限控制(保护代理): 在某些系统中,可能希望对访问某些资源进行权限控制。通过代理模式,可以在请求到达真实对象之前,对请求进行权限检查。

  3. 缓存管理(缓存代理): 如果某些对象的计算非常耗时或结果不会经常改变,可以使用缓存代理来缓存对象的计算结果。当再次请求时,直接从缓存中获取数据,避免重复计算。

  4. 远程代理: 远程代理可以让客户端像操作本地对象一样操作远程对象。例如,远程过程调用(RPC)就是通过代理模式实现的,客户端调用远程服务器上的方法时,代理对象会负责实际的远程调用。

  5. 日志记录(智能代理): 通过代理模式,在对真实对象的操作前后可以插入日志记录、性能监控等功能,而不改变真实对象的代码。

7. 代理模式的优缺点

优点:
  • 控制访问:代理模式可以用来控制对真实对象的访问,例如权限控制、延迟加载等。
  • 增强功能:可以在代理对象中增加额外的功能,例如缓存、日志记录、安全验证等,而无需修改真实对象的代码。
  • 降低耦合:客户端与真实对象的耦合度降低,客户端只与代理对象打交道,真实对象的变化不会直接影响到客户端。
缺点:
  • 增加复杂性:引入代理类可能增加系统的复杂度,尤其是如果代理对象的数量过多时,会使得系统变得更加难以维护。
  • 性能问题:代理模式引入了一个额外的对象,可能会导致一定的性能开销,尤其是在代理和真实对象交互频繁的情况下。

8. 总结

代理模式通过引入代理对象来控制对真实对象的访问,提供了更灵活的对象访问控制手段。它适用于延迟加载、权限控制、缓存等场景。通过代理,客户端可以与真实对象进行交互,而无需直接与真实对象打交道,从而降低了耦合度和系统的复杂性。在实际应用中,代理模式可以通过增强功能来提高系统的可扩展性和安全性。

版权声明
  1. 本文内容属于原创,欢迎转载,但请务必注明出处和作者,尊重原创版权。
  2. 转载时,请附带原文链接并注明“本文作者:扣丁梦想家
  3. 禁止未经授权的商业转载。

如果您有任何问题或建议,欢迎留言讨论。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/21452.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

七星棋牌源码高阶技术指南:6端互通、200+子游戏玩法深度剖析与企业级搭建实战(完全开源)

在棋牌游戏行业高速发展的今天&#xff0c;如何构建一个具备高并发、强稳定性与多功能支持的棋牌游戏系统成为众多开发者和运营团队关注的焦点。七星棋牌全开源修复版源码 凭借其 六端互通、200子游戏玩法、多省区本地化支持&#xff0c;以及 乐豆系统、防沉迷、比赛场、AI智能…

C++和OpenGL实现3D游戏编程【总览】

欢迎来到zhooyu的游戏专栏。 主页网址&#xff1a;【zhooyu】 专栏网址&#xff1a;【C和OpenGL实现3D游戏编程】 &#x1f31f;&#x1f31f;&#x1f31f;这里将通过一个OpenGL实现3D游戏编程实例教程&#xff0c;带大家深入学习OpenGL知识。知识无穷而人力有穷&#xff0c;…

pycharm社区版有个window和arm64版本,到底下载哪一个?还有pycharm官网

首先pycharm官网是这一个。我是在2025年2月16日9:57进入的网站。如果网站还没有更新的话&#xff0c;那么就往下滑一下找到 community Edition,这个就是社区版了免费的。PyCharm&#xff1a;适用于数据科学和 Web 开发的 Python IDE 适用于数据科学和 Web 开发的 Python IDE&am…

GPT-Sovits:语音克隆训练-遇坑解决

前言 本来以为3050完全无法执行GPT-Sovits训练的&#xff0c;但经过实践发现其实是可以&#xff0c;并且仅花费了十数分钟便成功训练和推理验证了自己的语音模型。 官方笔记&#xff1a;GPT-SoVITS指南 语雀 项目地址&#xff1a;https://github.com/RVC-Boss/GPT-SoVITS 本人…

8 SpringBootWeb案例(上): 查询【分页功能(分页插件)】、删除、新增、修改

文章目录 前言:SpringBootWeb案例1. 准备工作1.1 需求&环境搭建1.1.1 需求说明1.1.2 环境搭建1.2 开发规范1.2.1 开发规范-REST(不强求非要这种风格,传统风格有时候更方便)1.2.2 开发规范-统一响应结果和异常处理1.2.3 开发流程2. 部门管理2.1 查询部门2.1.1 原型和需求…

深入了解 DevOps 基础架构:可追溯性的关键作用

在当今竞争激烈的软件环境中&#xff0c;快速交付强大的应用程序至关重要。尽管如此&#xff0c;在不影响质量的情况下保持速度可能是一项艰巨的任务&#xff0c;这就是 DevOps 中的可追溯性发挥作用的地方。通过提供软件开发生命周期 &#xff08;SDLC&#xff09; 的透明视图…

用C++ Qt实现安卓电池充电动效 | 打造工业级电量控件

一、为什么需要自定义电池控件&#xff1f; 在工业控制、车机系统、智能硬件等领域的UI开发中&#xff0c;电池状态显示是高频出现的UI组件。通过实现一个支持颜色渐变、动态充电动画、警戒阈值提示的电池控件&#xff0c;开发者可以系统掌握以下核心能力&#xff1a; Qt绘图…

一批起飞猪名单配图

好久没有使用风口猪选股指标了&#xff0c;今天去玩了一把&#xff0c;发现起飞猪指标显示了好多一批猪票 华曙高科 汉威科技 双林股份 曼恩斯特 长盈精密 江苏雷利 双飞集团 奥飞数据 硅宝科技 水晶光电 长盈精密

机器学习笔记——常用损失函数

大家好&#xff0c;这里是好评笔记&#xff0c;公主号&#xff1a;Goodnote&#xff0c;专栏文章私信限时Free。本笔记介绍机器学习中常见的损失函数和代价函数&#xff0c;各函数的使用场景。 热门专栏 机器学习 机器学习笔记合集 深度学习 深度学习笔记合集 文章目录 热门…

Ubuntu 服务器Llama Factory 搭建DeepSeek-R1微调训练环境

1.首先了解一下什么是LLM微调 LLM 微调指的是在已经预训练好的大型语言模型基础上&#xff0c;使用特定的任务数据或领域数据&#xff0c;通过进一步的训练来调整模型的参数&#xff0c;使其在特定任务或领域上能够表现得更好。简单来说&#xff0c;就是对一个已经具备了丰富语…

环境变量与本地变量

目录 本地变量的创建 环境变量VS本地变量 认识完了环境变量我们来认识一下本地变量。 本地变量的创建 我们如果直接env是看不到本地变量的&#xff0c;因为本地变量和环境变量都具有独立性&#xff0c;环境变量是系统提供的具有全局属性的变量&#xff0c;都存在bash进程的…

智慧农业新生态 | 农业数字化服务平台——让土地生金,让服务无忧

一部手机管农事&#xff0c;从播种到丰收&#xff0c;全链路数字化赋能&#xff01; 面向农户、农机手、农服商、农资商打造的一站式农业产业互联网平台&#xff0c;打通农资交易、农机调度、农服管理、技术指导全场景闭环&#xff0c;助力乡村振兴提效增收。 三大核心场景&am…

【运维自动化-作业平台】如何创建执行方案和作业模板

蓝鲸智云作业平台&#xff0c;以下简称作业平台或JOB平台作业模板和执行方案&#xff1a;将运维操作场景中涉及到的多个脚本执行或文件分发步骤组合成一个作业模板&#xff0c;这个作业模板尽可能把场景相关的共性逻辑都包含进去&#xff0c;然后再根据实际使用场景衍生出相应的…

广度优先搜索--之重生之我是蒟蒻,从入坟到入坑式讲解

广度优先搜索 1.什么是广度优先搜索? 广度优先搜索&#xff08;Breadth-First Search&#xff0c;简称BFS&#xff09;是一种遍历或搜索树和图的算法&#xff0c;也称为宽度优先搜索&#xff0c;BFS算法从图的某个节点开始&#xff0c;依次对其所有相邻节点进行探索和遍历&am…

CSDN文章质量分查询系统【赠python爬虫、提分攻略】

CSDN文章质量分查询系统 https://www.csdn.net/qc 点击链接-----> CSDN文章质量分查询系统 <------点击链接 点击链接-----> https://www.csdn.net/qc <------点击链接 点击链接-----> CSDN文章质量分查询系统 <------点击链接 点击链…

为AI聊天工具添加一个知识系统 之113 详细设计之54 Chance:偶然和适配 之2

本文要点 要点 祖传代码中的”槽“ &#xff08;占位符变量&#xff09; 和 它在实操中的三种槽&#xff08;占据槽&#xff0c;请求槽和填充槽&#xff0c; 实时数据库&#xff08;source&#xff09;中数据(流入 ETL的一个正序流程 行列并发 靶向整形 绑定变量 &#xff09…

微信小程序实现拉卡拉支付

功能需求&#xff1a;拉卡拉支付&#xff08;通过跳转拉卡拉平台进行支付&#xff09;&#xff0c;他人支付&#xff08;通过链接进行平台跳转支付&#xff09; 1.支付操作 //支付 const onCanStartPay async (obj) > {uni.showLoading({mask: true})// 支付接口获取需要传…

Spring框架基本使用(Maven详解)

前言&#xff1a; 当我们创建项目的时候&#xff0c;第一步少不了搭建环境的相关准备工作。 那么如果想让我们的项目做起来方便快捷&#xff0c;应该引入更多的管理工具&#xff0c;帮我们管理。 Maven的出现帮我们大大解决了管理的难题&#xff01;&#xff01; Maven&#xf…

unity学习46:反向动力学IK

目录 1 正向动力学和反向动力学 1.1 正向动力学 1.2 反向动力学 1.3 实现目标 2 实现反向动力 2.1 先定义一个目标 2.2 动画层layer&#xff0c;需要加 IK pass 2.3 增加头部朝向代码 2.3.1 专门的IK方法 OnAnimatorIK(int layerIndex){} 2.3.2 增加朝向代码 2.4 …

力扣hot100——螺旋矩阵 超简单易懂的模拟搜索方法

给你一个 m 行 n 列的矩阵 matrix &#xff0c;请按照 顺时针螺旋顺序 &#xff0c;返回矩阵中的所有元素。 解法思路&#xff1a; // 模拟螺旋搜索设定四个边界// left right// top |————————————————|// | |// |…