概念
给某个对象提供一个代理对象,并由代理对象来控制对这个对象的访问。
代理对象会额外提供各类访问控制操作,达到增强对象的效果
应用场景
对于过于复杂的对象,访问操作非常复杂,这时候需要代理模式封装这部分访问操作。
客户端只需要访问代理对象,代理对象内部会处理各类复杂操作
基本结构

1)抽象主题接口(Subject):定义了真实对象和代理对象都需要实现的方法
2)真实主题(RealSubject):也就是目标对象,真正去执行核心业务逻辑的类
3)代理类(Proxy):实现和目标对象相同的接口,在内部维护一个真实对象的引用。代理类会控制对真实对象的访问,可能会在调用前后加点特殊的处理逻辑
代码实现
以图片懒加载为例
定义抽象主题接口
真实类和代理类都需要实现该接口,客户端只需要调用该接口即可,不需要关注底层实现
public interface Image {
void display();
}
定义真实主题
被代理对象,包含了各类操作方法,但对于业务逻辑过于复杂,需要代理类管理方法的调用,对外提供简单的调用方式
public class RealImage implements Image {
private String filename;
public RealImage(String filename) {
this.filename = filename;
loadFromDisk();
}
private void loadFromDisk() {
System.out.println("从磁盘加载图片:" + filename);
}
@Override
public void display() {
System.out.println("显示图片:" + filename);
}
}
定义代理类
通过代理类实现了懒加载,第一次展示图片时会调用loadFromDisk()方法,后续展示会直接展示
public 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 Client {
public static void main(String[] args) {
Image image = new ProxyImage("图片.png");
System.out.println("== 第一次显示图片 ==");
image.display(); // 会触发加载和显示
System.out.println("n== 第二次显示图片 ==");
image.display(); // 直接显示,不再加载
}
}
优缺点
优点
1)控制对象访问:通过代理类控制对目标对象的访问,有助于增强安全性、控制权限或延迟加载
2)增强目标对象:无需修改目标类代码即可添加额外功能,如缓存、日志、远程访问等,符合开闭原则
3)隔离客户端与目标对象:客户端通过代理与目标对象交互,有利于解耦
缺点
1)性能开销:动态代理或远程代理,可能带来反射、网络传输等额外开销
