JavaDog程序狗
发布于 2026-11-13 / 2 阅读
0
0

【设计模式】跟着狗哥复习设计模式(十二):代理模式

打开相册时,屏幕上可能有几十张图片。

要是每张大图都马上从磁盘读取,页面会做不少没必要的工作。用户可能只点开其中一张。

代理模式可以先派一个轻量对象顶着,需要时再找真实对象。

加瓦狗通过代理按需加载相册图片

所有图片一起加载,太着急了

真实图片对象一创建就读取文件。相册里对象一多,没点开的图片也会加载。

相册打开时提前加载全部大图

我们想要的效果很简单:创建图片条目时先别加载,用户点显示时再加载。

先看关键 UML 图

代理模式关键 UML 类图

ProxyImage 和 RealImage 都实现 Image。

客户端拿到的是代理对象,但调用方式和真实图片一样。代理内部会在合适的时机创建 RealImage。

先统一一个接口

public interface Image {
    void display();
}

客户端通过相同接口使用代理对象和真实对象

客户端只认 Image,不用改调用代码。

真实图片负责加载和显示

public class RealImage implements Image {
    private final String fileName;

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

    private void loadFromDisk() {
        System.out.println("从磁盘加载:" + fileName);
    }

    public void display() {
        System.out.println("显示图片:" + fileName);
    }
}

真正费事的加载动作,仍由 RealImage 完成。

代理先不创建真实图片

public class ProxyImage implements Image {
    private final String fileName;
    private RealImage realImage;

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

    public void display() {
        if (realImage == null) {
            realImage = new RealImage(fileName);
        }
        realImage.display();
    }
}

构造 ProxyImage 时只记住文件名。直到 display() 被调用,真实图片才出现。

第一次加载,后面直接显示

Image image = new ProxyImage("dog.jpg");
image.display();
image.display();

代理对象第一次和第二次显示图片的区别

输出:

从磁盘加载:dog.jpg
显示图片:dog.jpg
显示图片:dog.jpg

加载只发生一次,显示发生两次。青岛话说,第一回费点劲,后面就利索了。

代理和装饰器别混了

两者看起来都包着另一个对象,也常使用相同接口。

代理模式与装饰器模式的区别

代理更关心访问时机、权限或缓存。装饰器更关心增加新能力。

看目的,比背类图好使。

啥时候适合用代理

什么时候适合使用代理模式

图片延迟加载、权限检查、远程调用、本地缓存,都能见到代理的思路。

如果真实对象创建很轻,也没有访问控制需求,再包一层容易把代码写绕。

狗哥收个尾

代理模式的重点,是 让代理对象控制对真实对象的访问。

代理和真实对象使用同一个接口。客户端照常调用,代理决定何时创建、何时转交。

下一篇继续聊 责任链模式,看看一笔报销怎么一级一级往上审批。


评论