好问题!现在我们来讲解经典的结构型设计模式之一:代理模式(Proxy Pattern)。
我将通过:
✅ 一句话定义 + 🎯 为什么需要 + ✅ 优劣分析
🐍 Python完整代码(含注释)+ 🧭 类图 + 应用场景举例
一步步帮你掌握这个非常实用的模式。
🧠 一句话定义
代理模式是通过一个"代理对象",在访问真实对象前控制其访问、增强其功能,而不暴露真实对象的细节。
🎯 为什么需要代理?
场景 | 原因 |
---|---|
真实对象创建成本高 | 提供延迟加载(虚拟代理) |
需要访问控制 | 限制或鉴权(保护代理) |
需要功能增强 | 日志、缓存、性能统计(增强代理) |
客户端不应直接接触复杂实现 | 屏蔽内部结构(远程代理) |
✅ 优点 vs ❌ 缺点
✅ 优点 | ❌ 缺点 |
---|---|
控制访问,保护对象 | 增加类数目和复杂度 |
降低真实对象负担 | 调试复杂(多一层) |
动态增强功能(符合开闭原则) | 可能隐藏真正错误 |
🐍 Python 示例:图像加载代理(懒加载)
模拟"打开图像文件",但只有在真正需要时才加载
🖼️ 1️⃣ 抽象接口(Subject)
python
from abc import ABC, abstractmethod
class Image(ABC):
@abstractmethod
def display(self):
pass
📷 2️⃣ 真实对象(RealSubject)
python
class RealImage(Image):
def __init__(self, filename):
self.filename = filename
self.load_from_disk()
def load_from_disk(self):
print(f"🧾 加载图像文件: {self.filename}") # 模拟开销大
def display(self):
print(f"📷 显示图像: {self.filename}")
🪞 3️⃣ 代理类(Proxy)
python
class ProxyImage(Image):
def __init__(self, filename):
self.filename = filename
self.real_image = None # 尚未加载
def display(self):
if self.real_image is None:
# 懒加载:首次使用才创建真实对象
self.real_image = RealImage(self.filename)
self.real_image.display()
🧪 4️⃣ 客户端使用
python
# 创建代理图像对象(不立即加载)
img1 = ProxyImage("girl.jpg")
img2 = ProxyImage("logo.png")
# 实际显示时才加载真实图像
img1.display()
img1.display() # 第二次调用不会重新加载
img2.display()
✅ 输出结果
🧾 加载图像文件: girl.jpg
📷 显示图像: girl.jpg
📷 显示图像: girl.jpg
🧾 加载图像文件: logo.png
📷 显示图像: logo.png
🧭 类图(Mermaid)
组合关系 <<interface>> Image +display() RealImage +display() -load_from_disk() ProxyImage -real_image +display()
🧠 应用场景总结
类型 | 应用示例 |
---|---|
虚拟代理 | 图像/视频懒加载、延迟数据库连接 |
保护代理 | 权限校验、安全访问控制 |
远程代理 | 远程调用服务(RPC 框架) |
智能引用代理 | 引用计数、对象池、缓存管理 |
日志代理 | 增加日志、监控、统计时间等功能 |
✅ 总结口诀
"对象不想直接用,先找代理挡一挡"
✅ 代理模式让你在不改动原对象的前提下,控制、延迟或增强它的访问方式。
是否要我演示一个网络接口的请求代理、数据库缓存代理或 token 鉴权代理版本?我可以帮你按实际项目场景做一个专属 Proxy 模板!是否继续?