Skip to content

代理模式

代理模式(Proxy Pattern)是一种结构型设计模式,它为其他对象提供一个代理以控制对该对象的访问。代理模式可以用于多种场景,比如延迟初始化、访问控制、日志记录等。通过代理模式,可以在不改变原始对象的情况下添加额外的功能或控制访问。

代理模式的主要角色

  1. Subject(抽象主题角色):定义了 RealSubject 和 Proxy 的公共接口,这样就在任何使用 RealSubject 的地方都可以使用 Proxy。
  2. RealSubject(真实主题角色):定义了 Proxy 所代表的真实实体。
  3. Proxy(代理角色):持有对 RealSubject 的引用,并在调用 RealSubject 之前或之后执行一些操作,如创建 RealSubject 实例、记录日志等。

在 JavaScript 中的实现

下面是一个简单的代理模式示例,演示如何使用代理来控制对某个对象的访问:

示例:保护对昂贵资源的访问

javascript
// Subject(抽象主题角色)
class Image {
  constructor(filename) {
    this.filename = filename;
    this.loadFromDisk(); // 假设这是一个非常耗时的操作
  }

  display() {
    console.log(`Displaying ${this.filename}`);
  }

  loadFromDisk() {
    console.log(`Loading ${this.filename}`);
  }
}

// Proxy(代理角色)
class ImageProxy {
  constructor(filename) {
    this.filename = filename;
    this.image = null; // 延迟加载实际的Image对象
  }

  display() {
    if (!this.image) {
      this.image = new Image(this.filename); // 只有在需要时才加载图像
    }
    this.image.display();
  }
}

// 使用示例
const proxyImage = new ImageProxy("example.jpg");

// 图像尚未加载
proxyImage.display(); // 第一次调用会触发图像加载
proxyImage.display(); // 此次调用直接显示已加载的图像,不会再次加载

在这个例子中,Image 类代表了一个真实的主题角色,它模拟了一个从磁盘加载并显示图像的过程。而 ImageProxy 类则是代理角色,它控制了对 Image 实例的访问,在必要时才会真正地创建 Image 对象并加载图像。这种方式避免了不必要的资源加载,直到确实需要显示图像为止。

应用场景

代理模式适用于以下几种情况:

  • 虚拟代理:当需要处理开销很大的对象时,可以通过代理模式进行延迟加载。例如,上述示例中的图片加载。
  • 保护代理:基于权限控制对对象的访问。例如,只有具有特定权限的用户才能访问某些敏感信息。
  • 远程代理:为位于不同地址空间的对象提供本地代表。这使得客户端可以轻松地访问远程服务,就像是访问本地服务一样。
  • 智能引用:在访问对象时添加额外的操作,如计算引用计数、日志记录等。

总结

代理模式提供了一种灵活的方式,让我们可以在不改变原有类的基础上,增加额外的功能或者控制对对象的访问。这种模式特别适合于需要优化性能、增强安全性或简化复杂资源管理的应用场景。通过代理模式,我们可以有效地管理资源的使用,同时保持代码的清晰性和可维护性。

Released under the MIT License.