今天来用一个恋爱故事深入了解代理模式在 JavaScript 中的应用。
前言:面向对象编程基础
面向对象编程(OOP)是一种编程范式,它通过对象来组织代码。对象是数据和操作数据的方法的封装体。OOP 的核心概念包括:
- 封装:把数据和操作数据的方法放在一个对象里,隐藏内部细节。
- 继承:子类可以从父类那里获得属性和方法,避免重复代码。
- 多态:同一个方法名可以有不同的实现,使代码更灵活。
三角恋情背景
男女主角来了!! 假设在一个小镇上,有三个人:张无忌(ZhangWuJi)、赵敏(ZhaoMin)和小昭(XiaoZhao)。张无忌喜欢赵敏,但他害羞不敢直接表白。于是,他找到了他的好朋友小昭,希望通过小昭的帮助来表达自己的心意。
在这个故事中,我们定义三个对象:zhangwuji、zhaoMin 和 xiaozhao。小昭就是代理对象,她代表张无忌(目标对象)向赵敏(被代理对象)表达心意。我们可以通过下面 JavaScript 代码来模拟这个过程。 【这就是代理模式的应用】
先用对象字面量创建对象 这不需要用 new 关键字或类,直接用 {} 就行。对象字面量可以包含属性和方法,非常方便。例如:
const person = {
name: '张三',
age: 25,
sayHello: function() {
console.log(`你好,我是 ${this.name}`);//先自我介绍下下
}
};
person.sayHello(); // 输出: 你好,我是 张三
同样道理,用对象字面量创建 zhangwuji、zhaoMin 和 xiaozhao 三个对象,并且包含属性和方法。我们男主角张无忌 构建送花 sendFlower 方法,女主赵敏接花 receiveFlower, 小昭代表赵无极送花 sendFlower ,或是自己收到花 receiveFlower(看是自己留着,还是送给赵敏了)
const zhangwuji = {
name: '张无忌',
sendFlower: function(receiver) {
console.log(`${this.name} 给 ${receiver.name} 送了一束花`);
}
};
const zhaoMin = {
name: '赵敏',
xq:40,
receiveFlower: function(sender) {
console.log(`${this.name} 收到了来自 ${sender.name} 的花`);
}
};
const xiaozhao = {
name: '小昭',
sendFlower: function(receiver) {
// 小昭作为代理,代表张无忌送花
zhangwuji.sendFlower(receiver);
},
receiveFlower: function(sender) {
setTimeout(()=> {
zhaoMin.xq = 99;
zhaoMin.receiveFlower(sender);
},2000);
//或是代表赵无极,转送花给赵敏
zhaoMin.receiveFlower(sender);
//小昭也是大美女,也可以自己接花
// console.log(`${this.name} 收到了来自 ${sender.name} 的花`);
}
};
使用代理对象
接下来,我们通过小昭这个代理对象来帮助张无忌向赵敏表达心意。如果赵敏现在心情为40(满分100),赵无极让小昭等赵敏心情到达99,等2s后再代替自己送花给赵敏。
xiaozhao.sendFlower(zhaoMin);
运行上述代码,输出结果如下:
张无忌 给 赵敏 送了一束花
赵敏 收到了来自 张无忌 的花
好呐,剧情先发展到这一步~~
值得一说的是 -->> 代理模式是一种设计模式,它的主要目的是通过一个代理对象来控制对另一个对象的访问。代理模式的核心思想是通过代理对象间接访问目标对象,从而实现对目标对象的控制。
代理模式的优势
- 解耦:代理模式让目标对象和客户端之间解耦,客户端不需要直接与目标对象交互,而是通过代理对象间接访问。
- 增强功能:代理对象可以在调用目标对象的方法前后添加额外的操作,比如日志记录、权限检查等。
- 延迟初始化:代理对象可以在需要时才创建目标对象,实现懒加载。
举个例子说下三种优势
解耦:想象一下,如果你要寄一封信给朋友,你可以直接去邮局寄信,也可以让快递员帮你寄。如果每次都直接去邮局,你会很麻烦。但如果有一个快递员帮你寄信,你就只需要把信交给快递员,快递员再去邮局寄信。这样,你就和邮局解耦了,不需要直接打交道,事情变得更简单了。在编程中,代理模式也是一样的道理。客户端(你)不需要直接与目标对象(邮局)交互,而是通过代理对象(快递员)间接访问目标对象。这样,客户端和目标对象之间就解耦了,客户端只需要知道代理对象的存在,而不需要关心目标对象的具体实现。
增强功能:继续用寄信的例子,假设你在寄信之前,想在信封上贴一张漂亮的贴纸,或者在信里附上一张照片。如果你直接去邮局寄信,邮局的工作人员可能不会帮你做这些额外的事情。但如果你通过快递员寄信,快递员可以在帮你寄信之前,先帮你贴上贴纸或附上照片。在编程中,代理对象可以在调用目标对象的方法前后添加额外的操作。这些额外的操作可以是日志记录、权限检查、数据验证等。通过代理对象,我们可以在不修改目标对象的情况下,增强目标对象的功能。
延迟初始化:代理对象可以在需要时才创建目标对象,而不是一开始就创建。这样,可以节省系统资源,提高性能。例如,如果你有一个处理大量数据的对象,但这个对象只有在用户点击某个按钮时才需要使用,那么你可以在用户点击按钮时才创建这个对象,而不是一开始就创建。
如果觉得有收获,带走+点赞关注,后续持续更新