代理模式
特点
- 使用者无权访问目标对象
- 中间加代理,通过代理做授权控制
- 代理对象为基础对象提供不属于自己的一些特定的功能,或者完成业务上的特殊需求
介绍
-
代理模式原则上是将基础对象封装(但是与装饰器模式不同)
-
对内:并对基础对象进行监听以实现在特定环境下能特定的触发基础对象的功能
-
对外:保持与基础对象一致的对外接口,用以实现相同的功能
- 相同的对外接口对后期维护相当重要,当基础对象不再需要代理对象时,仅需要将代理对象剔除而不用修改调用该代理对象的方法
-
-
代理模式常用模式:保护代理、虚拟代理
- 保护代理:提前为基础对象过滤一些无意义或者非法的请求,降低错误率
- 虚拟代理:代理对象保持与基础对象一致调用方式,假设基础对象的激活十分复杂或占用资源较多,此时可先使用虚拟代理进行接收保存,在调用。
-
如下:
- 调用者调用代理类的方法,委托代理类调用 Super 基础类中的 receiverFlower 函数。
- 假设仅在基础类 state 为 happy 时可以进行调用,调用者并不知情,但代理类可以替调用者监听基础类的 state
- 变量的变化,并在合适的时候进行调用。 对于调用者不需要知道请求的时间只用关心我发出请求,以及结果。
- 而基础类也不用考虑非法的请求。所有的过滤、等待、监听操作全部由代理类进行执行。
demo
function Star() {
this.state = "nromal";
}
Star.prototype.getState = function () {
return this.state;
};
Star.prototype.setState = function (state) {
this.state = state;
};
// 假设 work 是一个 消耗性能的执行
Star.prototype.work = function () {
console.log("hello,word");
};
function Proxy(star) {
this.star = star;
}
Proxy.prototype.proxy = function(star){
this.star = star;
}
Proxy.prototype.work = function () {
if (this.star && this.star.getState() === "happy") {
this.star.work();
} else {
console.log("no work!");
}
};
const starA = new Star();
const ProxyA = new Proxy(starA);
ProxyA.work(); // 当star.state !== "happy" 会自动拦截请求(保护代理)
starA.setState("happy");
ProxyA.work(); // 虚拟代理 等到真正可以调用时,采取调用