共计 2447 个字符,预计需要花费 7 分钟才能阅读完成。
说到代理模式大家肯定不会模式在 ES6
中就有代理的语法糖,代理模式是一种结构型设计模式,其实从 ES6
的Proxy
中能够明确的感觉的出,一个客户不能或者不像间接拜访另一个对象,这是须要找一个中介帮忙实现某项工作,这个中介帮忙实现某项工作,这个中介就是代理对象。
举一个生存中的栗子,春节也行将邻近,大家在购买回家的车票的是偶不肯定要去火车站去买火车票,能够通过网上的一些平台或者去车票代售点去购买车票。这些网上的平台网站和代售车票的售票点都是代理模式的一种。在软件设计中,应用代理模式的例子也有很多,例如,要拜访的近程对象比拟大,下载可能须要很长很长的工夫,我这个时候咱们须要通过某个媒介去下载实现这步操作。
什么是代理模式
代理模式:是程序设计中的一种设计模式,为其余对象提供一种代理以管制对这个对象的拜访。在某些状况下,一个对象不适宜或者不能间接援用另一个对象,而代理对象能够在客户端和指标对象之间起到中介的作用。—— 节选自百度百科
代理模式分为两种模式,一种是动态代理,一种是动静代理,如果是动态代理的的话,须要批改 Proxy
类中构造函数的参数类型或者创立一个新的 Proxy
代理实现,因为对于动态代理来说,一旦代码谷底,则代理类就固定下来了,而通过动静代理,能够运行时,通过反射来创立代理类。其实这些也是代理模式的设计思维,通过代理的形式防止裸露被代理对象或者说代理不容易被获得的对象,这样就满足了开闭准则。
动态代理模式
动态代理模式在应用时,须要定义接口或者父类,被代理对象与代理对象一起实现雷同的接口或者时继承雷同的父类。
动态代理优缺点
动态代理类只能为特定的接口服务。如想要为多个接口服务则须要建设很多个代理类。
长处
- 在不批改指标对象的性能前提下,能通过代理对象对指标性能扩大
毛病
- 因为代理对象须要与指标对象实现一样的接口,所以会呈现很多的代理类
- 一旦接口减少办法,指标对象与代理对象都要保护
- 减少代理类之后显著会减少解决工夫,拖慢解决工夫
动态代理示例
动态代理的次要角色如下:
- 形象主题:是抽象类也能够是接口
- 具体主题角色:是业务逻辑的具体执行者
- 代理类:负责对实在角色的利用,把所有形象主题类定义的办法限度委托给实在主题角色实现,并且在实在主题角色处理完毕前后做预处理和善后处理工作
类图如下所示:
代码示例:
// 动态代理
interface Subject {doOperation() : void;
}
class RealSubject implements Subject {public doOperation() {console.log('我是 RealSubject 类,正在执行');
}
}
class MyProxy implements Subject {
private target : Subject;
constructor(realSubject : Subject) {this.target = realSubject;}
public doOperation() {console.log('我是代理类');
this.target.doOperation();}
}
function main() {const realSubject : Subject = new RealSubject();
const myProxy : Subject = new MyProxy(realSubject);
myProxy.doOperation();}
main();
动静代理模式
代理对象不须要实现接口,然而指标对象要实现接口,否则不能用动静代理。其中代理对象的生成,动静的在内存中构建代理对象。
动静代理优缺点
动静代理实质上依然是代理,代理类并不是在代码中定义的,而是在运行时依据咱们在代码中的 行为
动静生成的。
长处
代理对象不须要实现接口
毛病
减少代理对象之后显著会减少解决工夫,拖慢解决工夫
动静代理示例
动静代理的次要角色如下:
- 代理工厂类:生产次要代理类的工厂
- 形象主题:是抽象类也能够是接口
- 具体主题角色:是业务逻辑的具体执行者
- 代理类:负责对实在角色的利用,把所有形象主题类定义的办法限度委托给实在主题角色实现,并且在实在主题角色处理完毕前后做预处理和善后处理工作
类图如下所示:
代码示例:
// 动静代理
interface Subject {doOperation() : void;
}
class RealSubject implements Subject {constructor() {}
public doOperation() : void {console.log('我是 RealSubject 类,正在执行');
}
}
class ProxyFactory {
private target : any;
constructor(target : any) {this.target = target;}
public getProxyInstance() : any {
return new Proxy(this.target, {get: (target, propKey) => {
// 做的一些拦挡解决
return target[propKey];
}
});
}
}
function main() {const target : Subject = new RealSubject();
const proxyInstance:Subject<Subject> = new ProxyFactory(target);const instance = proxyInstance.getProxyInstance();
proxyInstance.doOperation();}
main();
总结
代理模式分为动态代理和动静袋理,动态代理类须要本人编写代码,动静代理,代理类通过代理工厂创立,不论是动态代理还是动静代理,代理与被代理都要实现两样接口,它们的本质是面向接口编程。
动态代理和动静代理的区别是在于要不要开发者本人定义 Proxy
类。动静代理通过 Proxy
动静生成 proxy class
,然而它也指定了一个InvocationHandler
的实现类。代理模式实质上的目标是为了加强现有代码的性能。