代理模式 (Proxy Pattern)
什么是代理模式?
代理模式是一种结构型设计模式,它允许你提供一个代理或占位符来控制对另一个对象的访问。
简单来说:代理模式就是给对象找一个"代理人",通过代理来访问对象。
生活中的例子
想象一下:
- 明星经纪人:经纪人代理明星处理事务
- 房产中介:中介代理房东出租房屋
- VPN:VPN代理访问国外网站
为什么需要代理模式?
传统方式的问题
java
// 直接访问对象
RealObject object = new RealObject();
object.doSomething();
问题:
- 无法控制:无法控制对对象的访问
- 无法增强:无法在访问前后添加额外逻辑
- 无法保护:无法保护对象不被直接访问
代理模式的优势
java
// 通过代理访问对象
Proxy proxy = new Proxy(new RealObject());
proxy.doSomething();
优势:
- 控制访问:可以控制对对象的访问
- 增强功能:可以在访问前后添加额外逻辑
- 保护对象:可以保护对象不被直接访问
代理模式的结构
┌─────────────────────┐
│ Subject │ 主题接口
├─────────────────────┤
│ + request(): void │
└──────────┬──────────┘
│ 实现
├──┬──────────────────┬──────────────┐
│ │ │
┌──────────┴──────┐ ┌───────────┴───────┐ ┌───┴────────┐
│ RealSubject │ │ Proxy │ │ ... │
├─────────────────┤ ├───────────────────┤ ├────────────┤
│ + request() │ │ - realSubject: RS │ │ │
└─────────────────┘ │ + request() │ │ │
└───────────────────┘ └────────────┘
代码示例
1. 定义主题接口
java
public interface Subject {
void request();
}
2. 定义真实主题
java
public class RealSubject implements Subject {
@Override
public void request() {
System.out.println("真实主题处理请求");
}
}
3. 定义代理
java
public class Proxy implements Subject {
private RealSubject realSubject;
@Override
public void request() {
if (realSubject == null) {
realSubject = new RealSubject();
}
System.out.println("代理:请求前处理");
realSubject.request();
System.out.println("代理:请求后处理");
}
}
4. 使用代理
java
public class Client {
public static void main(String[] args) {
Subject proxy = new Proxy();
proxy.request();
}
}
代理模式的类型
1. 远程代理
代理远程对象,隐藏网络细节。
2. 虚拟代理
延迟加载对象,只有在需要时才创建。
3. 保护代理
控制对对象的访问,提供权限控制。
4. 智能代理
在访问对象时添加额外逻辑,如引用计数、日志记录等。
代理模式的优点
- 控制访问:可以控制对对象的访问
- 增强功能:可以在访问前后添加额外逻辑
- 保护对象:可以保护对象不被直接访问
- 延迟加载:可以延迟加载对象
代理模式的缺点
- 增加复杂度:引入了额外的类
- 性能开销:多了一层调用
适用场景
- 控制访问:需要控制对对象的访问
- 延迟加载:需要延迟加载对象
- 远程访问:需要访问远程对象
- 权限控制:需要控制访问权限
常见应用场景
- RPC调用:远程过程调用
- 缓存:缓存代理
- 权限控制:权限控制代理
- AOP:面向切面编程
使用建议
- 控制访问:使用代理模式
- 延迟加载:使用代理模式
- 直接访问:直接使用即可
注意事项
⚠️ 代理模式虽然有用,但要注意:
- 不要过度使用,增加不必要的复杂度
- 考虑使用动态代理