HoRain云小助手个人主页 个人专栏: 《Linux 系列教程》《c语言教程》⛺️生活的理想就是为了理想的生活!⛳️ 推荐前些天发现了一个超棒的服务器购买网站性价比超高大内存超划算忍不住分享一下给大家。点击跳转到网站。专栏介绍专栏名称专栏介绍《C语言》本专栏主要撰写C干货内容和编程技巧让大家从底层了解C把更多的知识由抽象到简单通俗易懂。《网络协议》本专栏主要是注重从底层来给大家一步步剖析网络协议的奥秘一起解密网络协议在运行中协议的基本运行机制《docker容器精解篇》全面深入解析 docker 容器从基础到进阶涵盖原理、操作、实践案例助您精通 docker。《linux系列》本专栏主要撰写Linux干货内容从基础到进阶知识由抽象到简单通俗易懂帮你从新手小白到扫地僧。《python 系列》本专栏着重撰写Python相关的干货内容与编程技巧助力大家从底层去认识Python将更多复杂的知识由抽象转化为简单易懂的内容。《试题库》本专栏主要是发布一些考试和练习题库涵盖软考、HCIE、HRCE、CCNA等目录⛳️ 推荐专栏介绍生活中的代理比喻代理模式的核心组成1. 抽象主题(Subject)2. 真实主题(Real Subject)3. 代理(Proxy)代理模式的类型1. 虚拟代理(Virtual Proxy)2. 保护代理(Protection Proxy)3. 远程代理(Remote Proxy)4. 智能引用代理(Smart Reference Proxy)Python 实现代理模式基础接口定义实例真实主题实现实例代理类实现实例客户端代码实例实际应用示例图片加载代理图片加载系统实例保护代理示例访问控制实例代理模式的优缺点优点缺点代理模式的应用场景1. 懒加载(Lazy Loading)2. 访问控制(Access Control)3. 本地代表(Remote Representation)4. 日志记录(Logging)5. 缓存(Caching)实践练习练习 1缓存代理实例练习 2日志代理实例总结关键要点代理模式是一种结构型设计模式它为另一个对象提供一个替身或占位符以控制对这个对象的访问。简单来说代理就是一个中间人它在客户端和目标对象之间起到中介作用。生活中的代理比喻想象一下现实生活中的场景房产中介你不需要直接与房主沟通通过中介就能了解房源信息、安排看房明星经纪人厂商想要邀请明星代言需要通过经纪人来洽谈合作细节网络代理服务器你的网络请求先经过代理服务器再由代理服务器转发到目标网站在这些例子中中介/经纪人就是代理它们控制着对真实对象的访问。代理模式的核心组成代理模式通常包含三个关键角色1. 抽象主题(Subject)定义真实主题和代理主题的共同接口这样在任何使用真实主题的地方都可以使用代理主题。2. 真实主题(Real Subject)定义代理所代表的真实对象是最终要引用的对象。3. 代理(Proxy)保存一个引用使得代理可以访问实体提供一个与真实主题相同的接口控制对真实主题的访问。代理模式的类型代理模式有多种变体每种都有不同的应用场景1. 虚拟代理(Virtual Proxy)延迟创建开销很大的对象直到真正需要时才创建。2. 保护代理(Protection Proxy)控制对原始对象的访问用于对象应该有不同的访问权限时。3. 远程代理(Remote Proxy)为一个位于不同地址空间的对象提供本地代表。4. 智能引用代理(Smart Reference Proxy)在访问对象时执行额外的操作如引用计数、懒加载等。Python 实现代理模式让我们通过具体的代码示例来理解代理模式的实现。基础接口定义首先我们定义抽象主题接口实例from abc import ABC, abstractmethodfrom typing import Anyclass Subject(ABC):抽象主题接口定义真实主题和代理的共同操作abstractmethoddef request(self) - Any:执行请求的主要方法pass真实主题实现实例class RealSubject(Subject):真实主题类包含核心业务逻辑通常创建和初始化成本较高def __init__(self, name: str):self.name nameprint(f创建 RealSubject 实例: {self.name} (这是一个昂贵的操作))def request(self) - str:执行真实请求print(fRealSubject: 处理请求 - {self.name})return f来自 {self.name} 的响应代理类实现实例class Proxy(Subject):代理类控制对真实主题的访问可以添加额外的功能如懒加载、访问控制等def __init__(self, subject_name: str):self.subject_name subject_nameself._real_subject None # 延迟初始化def _lazy_init(self) - None:懒加载真实主题对象if self._real_subject is None:self._real_subject RealSubject(self.subject_name)def request(self) - str:代理的请求方法可以添加额外逻辑print(Proxy: 在调用真实对象前进行预处理)# 懒加载真实对象self._lazy_init()# 调用真实对象的方法result self._real_subject.request()print(Proxy: 在调用真实对象后进行后处理)return f代理增强的结果: {result}客户端代码实例def client_code(subject: Subject) - None:客户端代码通过抽象接口与主题交互不知道也不关心使用的是真实主题还是代理print(客户端: 开始执行操作)result subject.request()print(f客户端: 收到结果 - {result})print()# 使用示例if __name__ __main__:print(直接使用真实主题:)real_subject RealSubject(真实对象A)client_code(real_subject)print(使用代理:)proxy Proxy(代理对象B)client_code(proxy)# 再次使用同一个代理观察懒加载效果print(再次使用同一个代理:)client_code(proxy)运行上述代码你会看到以下输出直接使用真实主题: 创建 RealSubject 实例: 真实对象A (这是一个昂贵的操作) 客户端: 开始执行操作 RealSubject: 处理请求 - 真实对象A 客户端: 收到结果 - 来自 真实对象A 的响应 使用代理: 客户端: 开始执行操作 Proxy: 在调用真实对象前进行预处理 创建 RealSubject 实例: 代理对象B (这是一个昂贵的操作) RealSubject: 处理请求 - 代理对象B Proxy: 在调用真实对象后进行后处理 客户端: 收到结果 - 代理增强的结果: 来自 代理对象B 的响应 再次使用同一个代理: 客户端: 开始执行操作 Proxy: 在调用真实对象前进行预处理 RealSubject: 处理请求 - 代理对象B Proxy: 在调用真实对象后进行后处理 客户端: 收到结果 - 代理增强的结果: 来自 代理对象B 的响应实际应用示例图片加载代理让我们看一个更贴近实际的例子——图片加载的虚拟代理。图片加载系统实例from pathlib import Pathimport timeclass Image:真实图片类模拟加载大图片的昂贵操作def __init__(self, filename: str):self.filename filenameself._load_image()def _load_image(self) - None:模拟加载大图片的昂贵操作print(f正在加载图片: {self.filename} (这可能需要几秒钟...))time.sleep(2) # 模拟加载时间print(f图片 {self.filename} 加载完成!)def display(self) - None:显示图片print(f显示图片: {self.filename})class ImageProxy:图片代理实现懒加载def __init__(self, filename: str):self.filename filenameself._image Nonedef display(self) - None:显示图片如果需要则先加载if self._image is None:print(代理: 检测到图片未加载开始懒加载...)self._image Image(self.filename)else:print(代理: 图片已加载直接显示)self._image.display()# 使用示例def demo_image_proxy():print(创建图片代理 (不会立即加载图片))proxy ImageProxy(large_photo.jpg)print(\n第一次调用 display() - 触发懒加载:)proxy.display()print(\n第二次调用 display() - 直接使用已加载的图片:)proxy.display()# 运行示例demo_image_proxy()保护代理示例访问控制保护代理用于控制对敏感资源的访问。实例class SensitiveData:敏感数据类def __init__(self, data: str):self.data datadef read_data(self) - str:读取敏感数据return f敏感数据: {self.data}class ProtectionProxy:保护代理实现访问控制def __init__(self, sensitive_data: SensitiveData, user_role: str):self._sensitive_data sensitive_dataself.user_role user_roledef read_data(self) - str:读取数据但进行权限检查if self.user_role ! admin:return 错误: 权限不足只有管理员可以访问敏感数据return self._sensitive_data.read_data()# 使用示例def demo_protection_proxy():sensitive_data SensitiveData(机密信息: 项目预算为100万元)# 普通用户尝试访问user_proxy ProtectionProxy(sensitive_data, user)print(普通用户尝试访问:)print(user_proxy.read_data())# 管理员访问admin_proxy ProtectionProxy(sensitive_data, admin)print(\n管理员访问:)print(admin_proxy.read_data())demo_protection_proxy()代理模式的优缺点优点控制对象访问代理可以控制客户端如何以及与何时访问真实对象懒加载优化虚拟代理可以延迟创建昂贵对象提高性能增强安全性保护代理可以添加访问控制逻辑开闭原则可以在不修改客户端代码的情况下引入新的代理职责分离代理可以处理与核心业务逻辑无关的辅助功能缺点增加复杂性引入新的抽象层使代码结构更复杂响应延迟代理可能会增加请求的处理时间可能过度设计对于简单场景使用代理可能显得多余代理模式的应用场景代理模式在以下场景中特别有用1. 懒加载(Lazy Loading)当对象创建成本很高但可能不会立即使用时。2. 访问控制(Access Control)需要限制对某些对象的访问权限时。3. 本地代表(Remote Representation)为远程对象提供本地接口如 RPC 调用。4. 日志记录(Logging)在方法调用前后添加日志记录。5. 缓存(Caching)为昂贵操作的结果提供缓存。实践练习为了巩固对代理模式的理解尝试完成以下练习练习 1缓存代理创建一个缓存代理为计算斐波那契数列的函数添加缓存功能实例class FibonacciCalculator:计算斐波那契数列def fibonacci(self, n: int) - int:if n 1:return nreturn self.fibonacci(n - 1) self.fibonacci(n - 2)# 你的任务实现 FibonacciCacheProxy 类# 要求为斐波那契计算添加缓存避免重复计算class FibonacciCacheProxy:def __init__(self):self._calculator FibonacciCalculator()self._cache {} # 在这里实现缓存逻辑def fibonacci(self, n: int) - int:# 实现缓存逻辑pass# 测试代码def test_cache_proxy():proxy FibonacciCacheProxy()print(第一次计算 fib(10):)result1 proxy.fibonacci(10)print(f结果: {result1})print(第二次计算 fib(10) (应该从缓存获取):)result2 proxy.fibonacci(10)print(f结果: {result2})print(f两次结果相同: {result1 result2})练习 2日志代理创建一个日志代理记录方法的调用信息实例class DatabaseService:数据库服务def query(self, sql: str) - str:return f执行查询: {sql}def update(self, sql: str) - str:return f执行更新: {sql}# 你的任务实现 LoggingProxy 类# 要求记录每个方法的调用时间、参数和结果class LoggingProxy:def __init__(self):self._service DatabaseService()def query(self, sql: str) - str:# 添加日志记录逻辑passdef update(self, sql: str) - str:# 添加日志记录逻辑pass总结代理模式是一个强大的设计模式它通过引入中间层来控制对真实对象的访问。在 Python 中实现代理模式相对简单主要得益于 Python 的动态特性。关键要点代理是中介在客户端和真实对象之间充当中间人接口一致代理和真实对象实现相同的接口控制访问代理可以添加额外的控制逻辑如懒加载、权限检查等灵活应用根据需求选择不同类型的代理❤️❤️❤️本人水平有限如有纰漏欢迎各位大佬评论批评指正如果觉得这篇文对你有帮助的话也请给个点赞、收藏下吧非常感谢! Stay Hungry Stay Foolish 道阻且长,行则将至,让我们一起加油吧