结构型模式:代理模式
简介
代理模式指:由于某些原因需要给某对象提供一个代理以控制对该对象的访问。这时,访问对象不适合或者不能直接引用目标对象,代理对象作为访问对象和目标对象之间的中介。
更直白的说,代理模式更注重的是对源对象的控制访问(中介和保护),虽然我们可以在代理对象上扩展源对象没有的属性,但是如果要增强原有的功能其实还需要和其他模式进行组合使用,比如装饰器模式。
角色:
- 抽象角色:用于源对象与代理对象的依赖抽象
- 源对象:真实的业务对象,是代理类所要代表的真实对象
- 代理类:通过抽象角色规范,提供与源对象相同的接口,内部含有对源对象的引用,通过它可以进行扩展和控制
代码实现
//抽象
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对象,它不关心源对象的具体实现,它可以动态的拦截任何对象,只需要在一些更高层的接口处做具体的处理。
所以动态代理一般需要配合策略模式组合使用。
版权申明
本文系作者 @木灵鱼儿 原创发布在木灵鱼儿站点。未经许可,禁止转载。
暂无评论数据