自学教程 学编程从这里开始

代理模式

《代理模式》|设计模式系列第13篇

系列:结构型模式 · 代理模式(Proxy Pattern)
关键词:代理对象、控制访问、增强逻辑、静态代理、动态代理、远程代理

一、什么是代理模式

代理模式(Proxy Pattern):为其他对象提供一种代理以控制对这个对象的访问。

属于结构型设计模式。

简单理解:
代理对象和真实对象实现同一个接口。客户端访问代理对象,代理内部再去调用真实对象;可以在调用真实对象前后增加额外逻辑,而不用修改真实对象代码。代理就像经纪人,客户不和艺人直接对接,所有请求交给经纪人,经纪人可以做前置校验、日志、权限控制等操作。

核心意图
控制对真实对象的访问,在不修改真实对象代码前提下,增加额外逻辑。

适用场景

  1. 远程代理:访问远程服务对象(RMI)
  2. 虚拟代理:创建开销很大的对象,延迟加载
  3. 保护代理:权限校验,控制对象访问权限
  4. 智能引用:访问对象时附加日志、缓存、事务等逻辑

⚠️ 缺点预警:增加代理类,请求链路变长;部分场景会带来少量性能损耗。

二、UML结构图

角色划分:

  1. Subject(抽象主题):定义真实对象与代理对象共同实现的接口
  2. RealSubject(真实主题):实现核心业务逻辑
  3. Proxy(代理):持有RealSubject引用,实现Subject接口,控制访问并增强逻辑
  4. Client(客户端):面向Subject接口,调用代理对象

三、Java 完整示例

场景:Image 图片加载。高清图片加载耗时,使用代理实现虚拟代理,先展示占位图,真正需要显示时再加载大图。
代码全部使用英文。

1. Subject 抽象主题

public interface Image {
    void display();
}

2. RealSubject 真实主题

public class RealImage implements Image {
    private String fileName;

    public RealImage(String fileName) {
        this.fileName = fileName;
        loadFromDisk();
    }

    private void loadFromDisk() {
        System.out.println("Loading image from disk: " + fileName);
    }

    @Override
    public void display() {
        System.out.println("Display image: " + fileName);
    }
}

3. Proxy 代理类

public class ImageProxy implements Image {
    private String fileName;
    private RealImage realImage;

    public ImageProxy(String fileName) {
        this.fileName = fileName;
    }

    @Override
    public void display() {
        // 延迟加载,第一次display才创建真实对象
        if (realImage == null) {
            realImage = new RealImage(fileName);
        }
        realImage.display();
    }
}

4. Client 客户端

public class Client {
    public static void main(String[] args) {
        Image image = new ImageProxy("high_res_photo.jpg");
        System.out.println("Image proxy created, real image not loaded yet");
        image.display();
        image.display();
    }
}

运行输出:

Image proxy created, real image not loaded yet
Loading image from disk: high_res_photo.jpg
Display image: high_res_photo.jpg
Display image: high_res_photo.jpg

真实图片只在第一次调用display时加载,第二次调用直接复用已加载对象。

四、静态代理 vs 动态代理

  • Static Proxy:代理类在编译期手动编写,接口变更时代理类代码需要同步修改。示例代码就是静态代理。
  • Dynamic Proxy:运行期动态生成代理类,JDK动态代理(基于接口)、CGLIB动态代理(基于继承)。Spring AOP底层就是动态代理。

五、代理模式 vs 装饰器模式

模式目标核心
Proxy控制访问真实对象,对访问做管控代理代表真实对象,侧重访问控制
Decorator增强对象能力,动态叠加功能包装对象,侧重新增职责

六、优缺点总结

✅ 优点

  1. 客户端与真实对象解耦,通过代理控制访问
  2. 可以在业务前后增加日志、权限、缓存、事务等逻辑
  3. 虚拟代理实现延迟加载,优化资源开销
  4. 真实对象代码无侵入

❌ 缺点

  1. 增加代理类,代码结构变复杂
  2. 调用增加一层转发,存在微小性能开销
  3. JDK动态代理强制要求目标对象实现接口

七、框架源码应用

  • Spring AOP JDK Dynamic Proxy / CGLIB Proxy
  • JDK java.lang.reflect.Proxy
  • RMI Stub 远程代理

八、小结

代理模式核心:代理和真实对象实现同一接口,代理控制访问真实对象,附加额外逻辑。
静态代理适合简单场景;企业开发中最常用动态代理,Spring AOP就是动态代理的经典落地。

标签:

0 条笔记