代理模式是一种结构设计模式,它允许一个对象充当另一个对象的接口。代理通常控制着对于实际对象的访问,并且允许你在访问对象时添加额外的功能,比如验证、缓存等。

结构

  • 主题接口(Subject): 定义了代理和真实对象的共同接口,这样在任何使用真实对象的地方都可以使用代理。
public interface Subject {
    void request();
}
  • 真实主题类(Real Subject): 实现了主题接口,定义了代理所代表的真实对象。
public class RealSubject implements Subject {
    public void request() {
        System.out.println("Real Subject is handling the request.");
    }
}
  • 代理类(Proxy): 实现了主题接口,并且持有一个对真实主题对象的引用,负责控制访问真实对象。
public class Proxy implements Subject {
    private RealSubject realSubject;

    public Proxy(RealSubject realSubject) {
        this.realSubject = realSubject;
    }

    public void request() {
        // 添加额外功能
        System.out.println("Proxy is handling the request.");
        // 委托给真实主题对象处理请求
        realSubject.request();
    }
}

优点和缺点

优点:

  1. 代理对象可以控制实际对象的访问: 代理对象可以在调用实际对象之前或之后执行一些操作,比如权限控制、缓存、日志等。
  2. 降低了系统的耦合度: 代理对象可以在不改变实际对象的前提下,对外提供统一的接口,降低了系统的耦合度。
  3. 实现了延迟加载: 当需要大量初始化资源或者网络资源时,代理可以在需要时才进行加载,实现了延迟加载,提高了系统的性能和响应速度。

缺点:

  1. 增加了代码的复杂度: 由于引入了代理对象,系统会变得更加复杂。
  2. 可能降低系统的性能: 如果代理对象过于复杂,可能会引起性能问题,特别是在频繁调用时。

示例

假设我们有一个图像加载器,但是由于图像较大,我们希望在真正需要显示图像时再进行加载。我们可以使用代理模式实现延迟加载:

// 主题接口
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("Loading image: " + filename);
    }

    public void display() {
        System.out.println("Displaying image: " + filename);
    }
}

// 代理类
public class ProxyImage implements Image {
    private RealImage realImage;
    private String filename;

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

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

// 使用示例
public class Main {
    public static void main(String[] args) {
        Image image = new ProxyImage("example.jpg");
        // 图像在此时并未加载
        image.display();
        // 图像在此时加载并显示
    }
}

在这个例子中,ProxyImage 充当了 RealImage 的代理,它负责在需要时创建真正的 RealImage 对象,并调用其 display 方法。这样,当我们调用 display 方法时,代理会在需要时加载真实对象,实现了延迟加载。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注