代理模式(Proxy Pattern)是一种结构型设计模式,它允许通过一个代理对象来控制对另一个对象的访问。代理模式在不改变原始对象的情况下,通过引入代理对象来间接访问原始对象,从而在访问控制、延迟加载、缓存等方面提供了更多的灵活性和控制。
代理模式主要有三种角色:
-
抽象主题(Subject):定义了真实主题(RealSubject)和代理主题(Proxy)的共同接口,客户端通过该接口来访问真实主题和代理主题。
真实主题(RealSubject):是实际的业务对象,它是客户端直接访问的对象。 -
代理主题(Proxy):包含一个指向真实主题的引用,可以代理客户端的请求,并在真实主题的操作前后执行一些额外的操作。
代理模式可以分为不同类型,包括:静态代理:代理类在编译时已经确定,并且代理类和真实类是固定的。
动态代理:代理类在运行时动态生成,代理类和真实类是可以变化的。Java中的动态代理通过反射机制实现。
CGLIB代理:使用CGLIB库来生成代理类,它是通过继承来实现的,因此真实类不能是final类。
示例:假设我们有一个图片加载器的接口ImageLoader,和一个实现了该接口的真实图片加载器RealImageLoader,现在我们想要在图片加载前后添加一些额外的操作(例如:记录日志)。可以使用代理模式来实现。
// 抽象主题:图片加载器接口
interface ImageLoader {
void loadImage(String path);
}
// 真实主题:真实图片加载器
class RealImageLoader implements ImageLoader {
@Override
public void loadImage(String path) {
System.out.println("正在加载图片:" + path);
}
}
// 代理主题:图片加载器代理
class ImageLoaderProxy implements ImageLoader {
private ImageLoader realImageLoader;
public ImageLoaderProxy(ImageLoader realImageLoader) {
this.realImageLoader = realImageLoader;
}
@Override
public void loadImage(String path) {
System.out.println("记录日志:图片加载开始");
realImageLoader.loadImage(path);
System.out.println("记录日志:图片加载完成");
}
}
// 客户端代码
public class Client {
public static void main(String[] args) {
ImageLoader realImageLoader = new RealImageLoader();
ImageLoader proxyImageLoader = new ImageLoaderProxy(realImageLoader);
proxyImageLoader.loadImage("http://example.com/image.jpg");
}
}