目录
- 代理模式简介
- 代理模式的结构
- 代理模式的优缺点
- 代理模式的实现
- 4.1 Python 示例
- 代理模式的应用场景
- 出站链接
- 站内链接
- 参考资料
1. 代理模式简介
代理模式(Proxy Pattern) 是一种结构型设计模式,通过为其他对象提供代理对象来控制对这个对象的访问。代理对象是实际对象的“替身”,它可以在客户端和实际对象之间提供额外的功能,如延迟加载、访问控制、日志记录等。
为什么使用代理模式?
- 控制访问:通过代理类可以在访问实际对象之前进行一些控制或优化,比如权限控制、懒加载等。
- 增加功能:代理模式可以为目标对象提供附加的功能,如缓存、日志记录、事务控制等。
- 解耦:客户端不直接依赖于目标对象,代理类可以在不同的环境中替换目标对象,提供灵活性。
典型应用
- 虚拟代理:延迟加载对象的实例化,常用于图形图像加载、数据库连接等场景。
- 远程代理:代表一个远程对象,通过代理来与远程系统交互。
- 保护代理:控制对一个对象的访问,常用于访问控制或权限管理。
- 缓存代理:提供对象的缓存功能,当对象访问频繁时,通过代理返回缓存的结果,而不是每次都创建新对象。
2. 代理模式的结构
代理模式通常包括以下角色:
角色 | 作用 |
---|---|
Subject(主题接口) | 定义代理类和真实对象共同实现的接口。 |
RealSubject(真实主题类) | 真实对象,代理模式最终通过该对象提供具体的服务。 |
Proxy(代理类) | 代理类,通过代理类访问真实对象,控制对真实对象的访问。 |
Client(客户端) | 客户端通过代理类与真实对象进行交互。 |
UML 类图
┌─────────────────────┐
│ Client │
│ + operation() │
└──────────▲─────────┘
│
┌─────────────────────┐
│ Proxy │ (代理类)
│ + operation() │
└──────────▲─────────┘
│
┌─────────────────────┐
│ RealSubject │ (真实对象)
│ + operation() │
└─────────────────────┘
3. 代理模式的优缺点
✅ 优点
- 控制对象访问:代理类可以控制对目标对象的访问,提供额外的功能(如权限控制、延迟加载等)。
- 提高性能:代理可以实现对象的懒加载或缓存机制,提高系统性能。
- 解耦:客户端不需要直接访问真实对象,代理对象在不同情况下可以替换真实对象,增强系统的灵活性和扩展性。
❌ 缺点
- 性能开销:代理对象可能会增加一定的性能开销,尤其是在访问频繁时,因为每次操作都需要通过代理类转发。
- 增加系统复杂性:引入代理模式可能会增加系统的复杂性,尤其是在代理类和真实对象之间的协调和管理上。
4. 代理模式的实现
4.1 Python 示例
场景:假设我们有一个RealSubject
对象,它表示一个图像文件,而Proxy
类可以在访问图像文件时实现延迟加载,即当图像文件需要显示时才进行加载。
# 1. 主题接口:图像显示接口
class Image:
def display(self):
pass
# 2. 真实主题类:真实图像类
class RealImage(Image):
def __init__(self, filename):
self.filename = filename
self.load_image()
def load_image(self):
print(f"Loading image from {self.filename}")
def display(self):
print(f"Displaying image {self.filename}")
# 3. 代理类:图像代理类
class ProxyImage(Image):
def __init__(self, filename):
self.real_image = None
self.filename = filename
def display(self):
if self.real_image is None:
# 延迟加载图像
self.real_image = RealImage(self.filename)
self.real_image.display()
# 4. 客户端代码
if __name__ == "__main__":
image = ProxyImage("example.jpg")
# 第一次访问,图像会被加载
image.display() # 输出:Loading image from example.jpg Displaying image example.jpg
# 第二次访问,不需要加载图像
image.display() # 输出:Displaying image example.jpg
输出结果:
Loading image from example.jpg
Displaying image example.jpg
Displaying image example.jpg
在这个示例中,ProxyImage
是代理类,它在第一次访问时创建并加载实际的图像文件(RealImage
)。此后,当客户端再次请求图像时,代理类直接显示图像,而不需要再次加载文件,从而实现了延迟加载。
5. 代理模式的应用场景
适用于以下情况
- 控制访问:
- 当需要控制对真实对象的访问时,代理模式能够提供访问控制功能,例如权限检查、日志记录、缓存等。
- 延迟加载:
- 当对象创建成本较高或者资源较为昂贵时,代理可以延迟对象的加载,直到真正需要使用时才加载。
- 远程服务访问:
- 代理模式可以用于远程方法调用(RPC)中,客户端通过代理访问远程服务器上的对象。
- 缓存代理:
- 当访问的对象内容不频繁变化时,可以通过代理类缓存对象的状态,避免重复计算或访问。
真实案例
- 虚拟代理:在图形处理软件中,代理可以延迟加载图像,只有在图像需要显示时才加载。
- 远程代理:客户端通过代理访问远程服务,代理类负责在本地和远程对象之间传递请求。
- 保护代理:在一些系统中,代理类可以用来控制用户权限,只有具有足够权限的用户才能访问某些功能。
6. 出站链接
7. 站内链接
8. 参考资料
- Gamma, E., Design Patterns: Elements of Reusable Object-Oriented Software (1994).
- Freeman, E., Head First Design Patterns (2004).
总结
- 代理模式通过为目标对象提供一个代理类,控制了对目标对象的访问,可以增强系统的灵活性和扩展性。
- 代理模式适用于控制访问、延迟加载、远程访问、缓存等场景,例如虚拟代理、远程代理和保护代理。
- 代理模式增加了设计的灵活性,但也可能导致性能开销和系统复杂度的增加。
如果你有更多问题或希望进一步探讨,欢迎继续交流!🚀
发表回复