第11章:代理模式(Proxy Pattern)
一、导读
1.1 本章学习目标
第11章讲解代理模式——为其他对象提供一种代理以控制对这个对象的访问。
1.2 为什么第十一章如此重要
代理模式在远程调用、延迟加载、权限控制等场景中广泛应用。
1.3 核心问题引导
代理模式有哪些类型?
远程代理如何工作?
虚拟代理如何实现延迟加载?
保护代理如何控制访问?
二、核心概念详解
11.1 代理模式类型
代理模式类型:
- 远程代理:控制对远程对象的访问
- 虚拟代理:延迟创建昂贵对象
- 保护代理:控制访问权限
- 缓存代理:缓存请求结果
- 智能引用代理:在访问对象时执行额外操作11.2 虚拟代理
java
// 主题接口
public interface Image {
void display();
}
// 真实主题
public class RealImage implements Image {
private String filename;
public RealImage(String filename) {
this.filename = filename;
loadImageFromFile(); // 昂贵的操作
}
private void loadImageFromFile() {
System.out.println("Loading image: " + filename);
}
public void display() {
System.out.println("Displaying: " + filename);
}
}
// 代理
public class ImageProxy implements Image {
private String filename;
private RealImage realImage;
public ImageProxy(String filename) {
this.filename = filename;
}
public void display() {
if (realImage == null) {
realImage = new RealImage(filename); // 延迟创建
}
realImage.display();
}
}11.3 动态代理
java
// Java 动态代理
public interface Subject {
void request();
}
public class RealSubject implements Subject {
public void request() { System.out.println("RealSubject"); }
}
public class ProxyInvocationHandler implements InvocationHandler {
private Object target;
public ProxyInvocationHandler(Object target) {
this.target = target;
}
public Object invoke(Object proxy, Method method, Object[] args) {
System.out.println("Before");
Object result = method.invoke(target, args);
System.out.println("After");
return result;
}
}
// 使用
Subject proxy = (Subject) Proxy.newProxyInstance(
RealSubject.class.getClassLoader(),
new Class[]{Subject.class},
new ProxyInvocationHandler(new RealSubject())
);
proxy.request();三、实战案例
11.1 缓存代理
java
public class CachedService implements Service {
private Service realService;
private Map<String, Object> cache = new HashMap<>();
public Object request(String key) {
if (!cache.containsKey(key)) {
cache.put(key, realService.request(key));
}
return cache.get(key);
}
}四、本章小结
代理模式控制对对象的访问。虚拟代理延迟创建昂贵对象,动态代理在运行时创建代理。
五、思考与练习
代理模式有哪些类型?
虚拟代理如何实现延迟加载?
动态代理的原理是什么?
代理和装饰者有什么区别?
AOP 和代理模式有什么关系?