结构型——代理模式

结构型——代理模式

代理模式指的是通过创建一个代理来控制对原始对象的访问。代理在客户端与实际对象之间充当“中介”

特点

  • 访问控制:代理对象可以控制对实际对象的访问,从而实现对访问权限的控制。
  • 延迟加载:代理对象可以在实际对象被调用时才创建,从而实现延迟加载。
  • 解耦: 客户端金依赖代理接口,可以与实际对象分离,从而实现解耦。
  • 类型多样:虚拟代理(既延迟加载)、缓存代理(缓存对象)、远程代理(远程对象)、保护代理(权限控制)等。

模式结构

角色描述
抽象主题 (Subject)声明真实主题和代理主题的共同接口。客户端依赖此接口
真实主题 (RealSubject)实现抽象主题定义的接口,并提供其功能实现。实际执行业务逻辑的对象
代理主题 (Proxy)实现抽象主题定义的接口,并持有真实主题的引用。代理主题控制对真实主题的访问

代理模式类型

类型应用场景
虚拟代理当需要创建一个大开销的对象时,创建一个代理对象,直到需要时才创建真实的对象。
也叫延迟加载(比如在图片加载时,先加载一张占位图,当图片加载完成后再替换占位图)。
保护代理控制权限(在客户端对真实对象进行访问前,利用代理进行权限校验等操作)。
缓存代理缓存调用结果(为优化性能,将重复计算的值缓存起来,下次使用时直接返回缓存值)。
远程代理本地代理远程服务(将本地的请求转发到远程的对象上)。

简单示例

1. 虚拟代理

from abc import ABC, abstractmethod# 抽象主题
class Image(ABC):@abstractmethoddef display(self):pass# 真实主题(大开销对象)
class RealImage(Image):def __init__(self, filename):self.filename = filenameself.load_from_disk()def load_from_disk(self):print(f"Loading {self.filename} from disk")def display(self):print(f"Displaying {self.filename}")# 代理主题(控制加载时机)
class ProxyImage(Image):def __init__(self, filename):self.filename = filenameself.real_image = None      # 延迟加载def display(self):if not self.real_image:self.real_image = RealImage(self.filename)self.real_image.display()# 客户端代码
if __name__ == "__main__":# 创建代理,此时不会实际加载图片proxy_image = ProxyImage("test_image.jpg")             # Loading test_image.jpg from disk# 当需要展示时,实际去加载显示proxy_image.display()                                  # Displaying test_image.jpg

2. 保护代理

from abc import ABC, abstractmethod# 抽象主题
class DataBase(ABC):@abstractmethoddef query(self, sql):pass# 真实主题(实现对数据库的查询操作)
class RealDataBase(DataBase):def query(self, sql):return f"query result: {sql}"# 代理(对请求对象进行拦截,权限验证)
class ProxyDataBase(DataBase):def __init__(self, user):self.user = userself.real_db = RealDataBase()def query(self, sql):if self._check_access():return self.real_db.query(sql)else:return "access denied"def _check_access(self):return self.user == "admin"# 客户端代码
if __name__ == "__main__":proxy_db = ProxyDataBase("admin")print(proxy_db.query("select * from user"))         # query result: ....proxy_db = ProxyDataBase("guest")print(proxy_db.query("select * from user"))         # access denied

3. 缓存代理

from abc import ABC, abstractmethodclass Calculate(ABC):@abstractmethoddef calculate(self, n): passclass RealCalculate(Calculate):def calculate(self, n):return n * nclass ProxyCalculate(Calculate):def __init__(self):self.cache = {}self.real_calculate = RealCalculate()def calculate(self, n):if n not in self.cache:self.cache[n] = self.real_calculate.calculate(n)return self.cache[n]if __name__ == '__main__':proxy_calculate = ProxyCalculate()for i in range(10):print(proxy_calculate.calculate(i))         # 第一次计算,缓存for i in range(10):print(proxy_calculate.calculate(i))         # 第二次计算,直接从缓存中取

4.远程代理

import requestsclass BaiduService:def get_data(self, question): passclass BaiduServiceProxy(BaiduService):def __init__(self):self.question = questionself.baidu_api = "www.baidu.com"def get_data(self, question):response = requests.get(self.baidu_api, params={"question": question})return response.text# 客户端代码
if __name__ == "__main__":# 客户端仅与代理交互,无需感知远程服务的存在baidu_service = BaiduServiceProxy()data = baidu_service.get_data("如何使用代理模式")

代理模式 VS 外观模式 VS 装饰器模式 VS 适配器模式

维度代理模式外观模式装饰器模式适配器模式
核心目的控制对象访问简化复杂系统接口动态扩展对象功能接口兼容性转换
结构特点代理与真实对象实现相同接口外观类聚合多个子系统接口装饰器模式聚合被装饰对象适配器模式聚合被适配对象
对象关系代理对象持有真实对象外观持有多个子系统对象装饰器包裹原始对象适配器持有或继承被适配对象
接口一致性保持与真实对象接口一致提供新的简化接口保持与原始对象接口一致转换接口以匹配目标需求
扩展方向访问控制逻辑接口简化与整合功能叠加接口适配

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

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

相关文章

【算法】常见排序算法(插入排序、选择排序、交换排序和归并排序)

文章目录 前言一、排序概念及常见排序算法框图1.排序概念2.常见排序算法框图 二、实现比较排序算法1.插入排序1.1 直接插入排序1.2 希尔排序 2.选择排序2.1 直接选择排序2.2 堆排序 3.交换排序3.1 冒泡排序3.2 快速排序3.2.1 hoare版本3.2.2 挖坑法3.2.3 lomuto前后指针 3.3 快…

Go语言分布式锁实战:dlock助力构建高并发稳定系统

在构建分布式系统时,一个常见且棘手的问题便是资源竞争和数据一致性问题。分布式锁作为一种常用的解决方案,在多个进程或节点之间协调访问共享资源时显得尤为重要。今天,我们将介绍一款分布式锁库——dlock,并通过详细的使用示例带…

算法方法快速回顾

(待修改) 目录 1. 双指针2. 滑动窗口理论基础 3. 二分查找3. 二分查找理论基础 4. KMP5. 回溯算法6. 贪心算法7. 动态规划7.1. 01背包7.2. 完全背包7.3. 多重背包 8. 单调栈9. 并查集10. 图论10.1. 广度优先搜索(BFS)10.2. 深度优…

深度学习:让机器学会“思考”的魔法

文章目录 引言:从“鹦鹉学舌”到“举一反三”一、深度学习是什么?1. 定义:机器的“大脑”2. 核心思想:从数据中“悟”出规律 二、深度学习的“大脑”结构:神经网络1. 神经元:深度学习的基本单元2. 神经网络…

电动自行车/电动工具锂电池PCM方案--SH367003、SH367004、SH79F329

在消费电子系统中,如手机电池包,笔记本电脑电池包等,带有控制IC、功率MOSFETFE管以及其他电子元件的电路系统称为电池充放电保护板Protection Circuit Module (PCM),而对于动力电池的电池管理系统&#xff…

补码详细分析

补码引入 举一个生活化的例子 假设由一个挂钟,它只能顺时钟调时间,那么它调时间就分成了一下两种情况 正好顺时针调就能调好 如:时针从5调到9需要逆时针调才能调好 如:时针从10调到7 在上面的情况中1是不用处理的,2…

计算机网络入门:物理层与数据链路层详解

🌐 (专业解析 中学生也能懂!) 📖 前言 计算机网络就像数字世界的“高速公路系统”,而物理层和数据链路层是这条公路的基石。本文用 专业视角 和 生活化比喻 ,带你轻松理解这两层的核心原理&a…

哪些视频格式在webview2中播放可以设置成透明的?

在WebView2中,能够播放并设置成透明背景的视频格式主要取决于其支持的编解码器以及视频是否包含alpha通道(透明度信息)。以下是支持透明背景的视频格式: 支持透明背景的视频格式 1. WebM(使用VP9编解码器) …

【基于ROS的A*算法实现路径规划】A* | ROS | 路径规划 | Python

### 记录一下使用Python实现ROS平台A*算法路径规划 ### 代码可自取 :Xz/little_projecthttps://gitee.com/Xz_zh/little_project.git 目录 一、思路分析 二、算法实现 三、路径规划实现 一、思路分析 要求使用A*算法实现路径规划,可以将该任务分为三…

2025-03-23 吴恩达机器学习3——多维特征

文章目录 1 多元引入2 矢量化2.1 示例2.2 非矢量化实现2.3 矢量化实现2.4 应用 3 特征缩放3.1 举例3.2 必要性3.3 方法3.3.1 最大最小值缩放(Min-Max Scaling)3.3.2 均值归一化(Mean Normalization)3.3.3 Z 分数归一化&#xff08…

正点原子内存管理学习和修改

由于项目需要用到内存管理进行动态申请和释放,今天又重新学习了一下正点原子的内存管理实验,温习了一下内存管理的实质。首先先上正点原子内存管理的源代码: malloc.c文件: #include "./MALLOC/malloc.h"#if !(__ARMC…

时空观测者:俯身拾贝

目录 中华文明时空贝壳集(按时间排序)1. 良渚玉琮(约公元前3300-2300年)2. 三星堆青铜神树(公元前1200年)3. 殷墟甲骨文(约公元前14世纪)4. 京杭大运河(公元前486年始建&…

护网期间监测工作全解析:内容与应对策略

护网期间监测工作全解析:内容与应对策略 一、引言 在数字化浪潮中,网络安全的重要性愈发凸显,护网行动作为保障关键信息基础设施安全的关键举措,备受瞩目。护网期间,监测工作是发现潜在威胁、防范攻击的重要防线。全…

【Centos7搭建Zabbix4.x监控HCL模拟网络设备:zabbix-server搭建及监控基础05

兰生幽谷,不为莫服而不芳; 君子行义,不为莫知而止休。 5.zabbix监控HCL模拟网络设备 在保证zabbix-server与HCL网络相通的情况下进行如下操作。 5.1创建主机群 配置-主机群-创建主机群 图 19 取名,添加。 图 20 5.2 创建监控…

趣味极简品牌海报艺术贴纸设计圆润边缘无衬线粗体装饰字体 Chunko Bold - Sans Serif Font

Chunko Bold 是一种功能强大的显示字体,体现了大胆极简主义的原则 – 当代设计的主流趋势。这种自信的字体将粗犷的几何形状与现代的趣味性相结合,具有圆润的边缘和强烈的存在感,与当今的极简主义设计方法完美契合。无论是用于鲜明的构图还是…

Spring Boot(十七):集成和使用Redis

Redis(Remote Dictionary Server,远程字典服务器)是一个开源的、基于内存的数据结构存储系统,它可以用作数据库、缓存和消息中间件。Spring Boot 中集成和使用Redis主要涉及以下几个步骤: 添加依赖 在项目的pom.xml文件中添加Redis的依赖。Spring Boot提供了对Redis的集…

2025-03-21 Unity 序列化 —— 自定义2进制序列化

文章目录 前言1 项目结构1.1 整体1.2 代码 2 实现2.1 Processor2.1.1 BaseType2.1.2 CollectionType2.1.3 CustomType 2.2 ByteFormatter2.3 ByteHelper 3 使用 前言 ​ BinaryFormatter 类可以将 C# 类对象快速转换为字节数组数据。 ​ 在网络开发时,不会使用 Bi…

为WordPress自定义一个留言板

要在WordPress中创建一个留言反馈表单,并实现后台管理功能,您可以按照以下步骤进行操作: 1. 创建留言反馈表单 首先,您需要使用一个表单插件来创建表单。推荐使用 Contact Form 7 或 WPForms。以下是使用 Contact Form 7 的示例…

嵌入式项目:利用心知天气获取天气数据实验方案

【实验目的】 1、利用心知天气服务器获取指定位置天气数据 2、将天气数据解析并可视化显示到OLED屏幕 【实验原理】 【实验步骤】 官网注册

go-zero学习笔记

内容不多,只有部分笔记,剩下的没有继续学下去,包括路由与处理器、日志中间件、请求上下文 文章目录 1、go-zero核心库1.1 路由与处理器1.2 日志中间件1.3 请求上下文 1、go-zero核心库 1.1 路由与处理器 package mainimport ("github…