代理模式
外观
代理模式[编辑 | 编辑源代码]
代理模式(Proxy Pattern)是一种结构型设计模式,它为其他对象提供一种代理以控制对这个对象的访问。代理模式在不改变原始类代码的情况下,通过引入代理类来间接访问目标对象,从而实现对目标对象的保护、延迟加载、访问控制等功能。
模式结构[编辑 | 编辑源代码]
代理模式包含以下主要角色:
- Subject(抽象主题):声明真实主题和代理主题的共同接口,客户端通过该接口访问真实主题。
- RealSubject(真实主题):定义代理所代表的真实对象,是客户端最终要访问的对象。
- Proxy(代理):持有对真实主题的引用,控制对真实主题的访问,并可能负责创建和删除它。
代码示例[编辑 | 编辑源代码]
以下是一个简单的代理模式示例,展示如何通过代理控制对真实对象的访问:
// 抽象主题
interface Image {
void display();
}
// 真实主题
class RealImage implements Image {
private String filename;
public RealImage(String filename) {
this.filename = filename;
loadFromDisk();
}
private void loadFromDisk() {
System.out.println("Loading image: " + filename);
}
@Override
public void display() {
System.out.println("Displaying image: " + filename);
}
}
// 代理
class ProxyImage implements Image {
private RealImage realImage;
private String filename;
public ProxyImage(String filename) {
this.filename = filename;
}
@Override
public void display() {
if (realImage == null) {
realImage = new RealImage(filename); // 延迟加载
}
realImage.display();
}
}
// 客户端代码
public class ProxyPatternDemo {
public static void main(String[] args) {
Image image = new ProxyImage("test.jpg");
// 图像将从磁盘加载
image.display();
System.out.println("---");
// 图像不需要再次加载
image.display();
}
}
输出结果:
Loading image: test.jpg Displaying image: test.jpg --- Displaying image: test.jpg
代理模式类型[编辑 | 编辑源代码]
代理模式有多种变体,常见的包括: 1. 虚拟代理:延迟创建开销大的对象(如上述图像加载示例)。 2. 保护代理:控制对原始对象的访问权限。 3. 远程代理:为位于不同地址空间的对象提供本地代表(如RPC调用)。 4. 智能引用代理:在访问对象时执行附加操作(如引用计数、线程安全检查等)。
实际应用案例[编辑 | 编辑源代码]
1. Spring AOP[编辑 | 编辑源代码]
Spring框架使用代理模式实现面向切面编程(AOP)。当使用@Transactional注解时,Spring会创建目标对象的代理,在方法调用前后添加事务管理逻辑。
2. 缓存代理[编辑 | 编辑源代码]
代理可以用于实现缓存机制,当客户端请求数据时,代理首先检查缓存,如果存在则直接返回,否则访问真实对象并将结果缓存。
class DataFetcher:
def fetch_data(self, key):
# 模拟耗时操作
print(f"Fetching data for key: {key}")
return f"Data for {key}"
class CachingProxy:
def __init__(self, real_fetcher):
self.real_fetcher = real_fetcher
self.cache = {}
def fetch_data(self, key):
if key not in self.cache:
self.cache[key] = self.real_fetcher.fetch_data(key)
return self.cache[key]
# 使用示例
fetcher = CachingProxy(DataFetcher())
print(fetcher.fetch_data("user1")) # 从真实对象获取
print(fetcher.fetch_data("user1")) # 从缓存获取
优缺点[编辑 | 编辑源代码]
优点:
- 可以在不修改目标对象的情况下扩展其功能
- 将客户端与目标对象分离,降低系统耦合度
- 可以实现精细化的访问控制
- 支持延迟加载和按需创建对象
缺点:
- 可能增加系统复杂度
- 代理调用可能引入轻微的性能开销
- 某些代理模式实现需要生成额外类(如动态代理)
数学表示[编辑 | 编辑源代码]
代理模式可以形式化表示为:
总结[编辑 | 编辑源代码]
代理模式是一种强大的设计模式,它通过引入间接层提供了对目标对象的灵活控制。理解代理模式有助于开发者设计更灵活、可维护的系统架构,特别是在需要控制对象访问或添加横切关注点时。