这是我参与「第四届青训营」笔记创作活动的的第 4 天
23 种设计模式
- 创建型:如何创建一个对象
- 结构型:如何灵活地将对象组装成较大的结构
- 行为型:负责对象间的搞笑通信和职责划分
浏览器中的设计模式
单例模式
存在一个全局唯一访问的对象,在全局人任意地方访问到的都是同一个对象,其中最常见的就是浏览器中的 window。
应用场景
全局的缓存、全局状态管理等。
单例模式实现请求缓存的栗子
import { api } from './utils';
const cache: Record<string, string> = {};
export const request = async (url: string) => {
if (cache[url]) return cache[url];
const response = await api(url);
return (cache[url] = response);
}
这样的话如果我们请求同一个地址多次,第一次会进行请求并缓存到 cache 变量中,而后续的相同地址的请求会直接从缓存中读取。
发布订阅模式
发布订阅模式是一种订阅机制,可在被订阅对象发生变化时通知订阅者。
应用场景
从系统架构之间的解耦,到业务中一些实现模式,如邮件订阅,上线订阅等。
JavaScript 中的 addEventListener 就是一种发布订阅模式,旨在触发事件的时候能够触发对应的事件监听器。
JavaScript 中的设计模式
原型模式
原型模式是指复制已有的对象来创建新的对象。
在 JavaScript 中,可以使用 Object.create(protoObject) 来基于创建一个基于 protoObject 的新对象。
代理模式
可以自定义控制原对象的访问方式,并且允许在更新的前后做一定的处理。
JavaScript 中可以使用 Proxy 来实现对对象的代理。
new Proxy(originObject, {
set: () => {},
// ...
})
应用场景
监控,代理工具,前端框架实现等。
Vue3 就是使用代理来实现自动更新 DOM。
迭代器模式
迭代器模式旨在不暴露数据类型的情况下访问集合中的数据。
在 JavaScript 中可以为一个对象定义 Symbol.iterator 生成器函数来使得对象可以被迭代。
myIterable[Symbol.iterator] = function* () {
yield 1;
yield 2;
yield 3;
};
总结
- 总结出抽象的模式相对比较简单,但是想要将抽象的模式套用到场景中却非常困难。
- 现在编程语言的多变成范式带来的更多可能性。
- 真正优秀的开源项目学习设计模式并不断实践。
因此设计模式并不是银弹,我们要学习的是设计模式中的思想。
参考
- 字节跳动青训营 - 前端设计模式应用
- mdn web docs