设计模式,其实就是为软件设计中普遍存在的各种问题所提出的各种方案。
# 单例模式
概念:全局作用域下只会创建一次实例对象,让所有需要调用的地方都共享这一单例对象。
应用场景:
- 全局模态框
- vuex、vue-router、redux
class Singleton {
private static instance = null
public static getInstance() {
if (Singleton.instance === null) {
Singleton.instance = new Singleton()
}
return Singleton.instance
}
// ...
}
export const singleton = Singleton.getInstance()
# 工厂模式
概念:创建对象的常用设计模式,不暴露创建对象的具体逻辑,而是将逻辑封装在一个函数(工厂)中。
应用场景:
- 创建对象
function newFactory(constructor, ...args) {
const obj = new Object()
obj.__proto__ = constructor
const res = constructor.apply(obj, args)
return typeof res === 'object' ? res : obj
}
- 原型式继承
function extendFactory(parent) {
const obj = new Object()
obj.__proto__ = parent
return obj
}
# 策略模式
定义一系列算法,并且将它们一个个封装起来,将算法的使用和算法的实现分离开来
- 策略类:可变。封装不同策略的算法。
- 环境类:不可变。接收不同的客户请求,将其委托给对应的策略。
应用场景:
表单验证
- 策略类:不同的验证逻辑
- 环境类:接收用户验证要求,委托给不同的策略
对接不同应用接口,如:对接微信、抖音等不同应用的登录接口
- 策略类:不同应用的登录接口
- 环境类:接收不同应用的用户登录请求,委托给不同的策略
# 观察者模式
概念:
定义了对象之间的一种一对多的依赖关系。当一个对象的状态发生改变时,依赖于它的所有对象都会得到通知,使其自动更新。
行为型模式:关注的是对象之间的通讯(观察者和被观察者之间的通信)
观察者与被观察者直接交互
被观察者知道有哪些观察者
应用场景:
- Vue2 响应式实现:观察者模式 + Object.defineProperties
- 被观察者:data 数据
- 观察者:各种 Watcher,如:Render Watcher、Computed Watcher 等。
# 发布订阅模式
概念:
- 发布订阅是一种消息范式
- 发布者不会将消息直接发送给订阅者,而是将消息分为不同的类别,无需了解哪些订阅者可能存在(消息代理进行通信)
应用场景:
- EventBus
# 观察者模式 vs 发布订阅模式
观察者模式
- 行为式模式
- 被观察者知道有哪些观察者
- 被观察者与观察者直接通信
发布订阅模式
- 消息范式
- 发布者不知道有哪些订阅者
- 发布者和订阅者不会直接通信,
- 而是将消息分为不同的类别,通过事件代理的方式,通知订阅者
# 代理模式
概念:为一个对象提供一个代用品或者占位符,控制该对象的访问。
应用:
- Proxy 对象
- 缓存代理:将计算开销比较大的数据进行缓存,二次计算的时候命中缓存直接从缓存里面获取计算结果。
- 虚拟代理:图片懒加载。
# 装饰者模式
概念:
- 在不改变对象自身的基础上,在程序运行期间给对象动态添加额外的方法。
- 将类的核心职责和装饰功能区分开来。
应用场景:
- 动态地扩展对象功能
- 避免过度子类化:有多个功能相似但略有不同的对象。
← 用户认证小总结