简介

代理模式指:由于某些原因需要给某对象提供一个代理以控制对该对象的访问。这时,访问对象不适合或者不能直接引用目标对象,代理对象作为访问对象和目标对象之间的中介。

更直白的说,代理模式更注重的是对源对象的控制访问(中介和保护),虽然我们可以在代理对象上扩展源对象没有的属性,但是如果要增强原有的功能其实还需要和其他模式进行组合使用,比如装饰器模式。

角色:

  1. 抽象角色:用于源对象与代理对象的依赖抽象
  2. 源对象:真实的业务对象,是代理类所要代表的真实对象
  3. 代理类:通过抽象角色规范,提供与源对象相同的接口,内部含有对源对象的引用,通过它可以进行扩展和控制

代码实现

//抽象
interface AInterface {
  name: string;
  age: number;

  getName(): string;
  getAge(): number;
}

//源对象
class AClass implements AInterface {
  public name: string;
  public age: number;

  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }

  public getName(): string {
    return this.name;
  }

  public getAge(): number {
    return this.age;
  }
}

//代理对象
class ProxyClass implements AInterface {
  private _target: AClass;

  constructor(name: string, age: number) {
    this._target = new AClass(name, age);
  }

  public get name() {
    return this._target.name;
  }

  public get age() {
    return this._target.age;
  }

  public getName(): string {
    return this._target.getName();
  }

  public getAge(): number {
    return this._target.getAge();
  }

  //增加新功能
  public getNameAndAge(): string {
    return `${this.name} ${this.age}`;
  }
}

在代理类中对源对象的引用,其实不必局限于组合的形式,可以通过传参的形式接,这也是可以的,因为代理类更强调的是对源对象的访问控制。

静态代理

静态代理的特点就是代理类和源对象在代码中是确定的,他不是运行时的,因此称为静态代理。上面的代码就是一个静态的代理。

为了能够规范,所以静态代理需要声明一个接口去抽象需要代理源对象的属性,这就导致如果源对象新增了新的属性,代理类乃至接口都需要进行改动,违反了开闭原则。

为此就有了动态代理。

动态代理

动态代理是对运行时的对象代理的方式,它的底层不用我们亲自实现,一般都是由系统提供对应的接口来使用,并且不需要一一实现源对象的属性或者方法,而是通过拦截的方式动态的代理属性或者方法,通过一些更高层的逻辑接口实现拦截。

比如js中的proxy对象,它不关心源对象的具体实现,它可以动态的拦截任何对象,只需要在一些更高层的接口处做具体的处理。

所以动态代理一般需要配合策略模式组合使用。

分类: 设计模式 标签: 设计模式代理模式结构型模式静态代理动态代理

评论

暂无评论数据

暂无评论数据

目录