列举
创建型
- 要点
- 提供创建对象的机制, 能够提升已有代码的灵活性和可复用性。
- 工厂方法
- 抽象工厂
- 生成器
- 原型
- 单例
结构型
- 要点
- 考虑的是对象的组成和对象之间的关系,假如对象发生了重大改变,对当前对象操作影响降至最低
- 将对象和类组装成较大的结构, 并同时保持结构的灵活和高效。
- 适配器模式
- 桥接模式
- 组合
- 装饰器模式
- 外观模式
- 享元模式
- 代理模式
行为型
- 要点
- 关注的是对象之间的依赖关系以及通信
- 负责对象间的高效沟通和职责委派。
- 责任链
- 命令
- 迭代器
- 中介者
- 备忘录
- 观察者
- 状态
- 策略
- 模板方法
- 访问者
前端常用
- 单例模式
- 观察者模式(发布订阅模式)
- redux
- 命令模式
- s3
- 策略模式
- 大幅度减少多重条件下的判断
有助于提高系统的可拓展性
- 工厂模式
- 抽象工厂模式
- 观察者模式: 观察者很容易增加
- 适配器模式: 适配新的接口
- 代理模式: 在原来的功能上增加新功能或逻辑
- 责任链模式: 通过新增拦截器/过滤器来实现对数据的处理
- 策略模式: 新增策略
发布订阅
定义
- 发布-订阅模式其实是一种对象间一对多的依赖关系。
- 当一个对象的状态发送改变时,所有依赖于它的对象都将得到状态改变的通知。
- 三个角色(订阅者,调度中心,发布者)
- 流程:订阅者(Subscriber)把自己想订阅的事件注册(Subscribe)到调度中心(Event Channel),当发布者(Publisher)发布该事件(Publish Event)到调度中心,也就是该事件触发时,由调度中心统一调度(Fire Event)订阅者注册到调度中心的处理代码。
实现
class EventEmitter{
constructor(){
this._events = {};
}
on(eventName, callback){
if(this._events[eventName]){
if(this.eventName !== "newListener"){
this.emit("newListener", eventName)
}
}
const callbacks = this._events[eventName] || [];
callbacks.push(callback);
this._events[eventName] = callbacks
}
emit(eventName, ...args){
const callbacks = this._events[eventName] || [];
callbacks.forEach(cb => cb(...args))
}
once(eventName, callback){
const one = (...args)=>{
callback(...args)
this.off(eventName, one)
}
one.initialCallback = callback;
this.on(eventName, one)
}
off(eventName, callback){
const callbacks = this._events[eventName] || [];
const newCallbacks = callbacks.filter(fn => fn != callback && fn.initialCallback != callback /* 用于once的取消订阅 */)
this._events[eventName] = newCallbacks;
}
}
EventBus
- 指greenrobot/EventBus: Event bus for Android and Java that simplifies communication between Activities, Fragments, Threads, Services, etc. Less code, better quality.
- 发布订阅模式
- 使用: 参见 EventBus 使用(全面分析,细节提醒) - 似水流云 - 博客园
区别于观察者模式
- 观察者是经典软件设计模式中的一种,但发布订阅只是软件架构中的一种消息范式。
- 观察者模式本身只需要2个角色便可成型,即观察者和被观察者,其中被观察者是重点。
- 发布订阅需要至少3个角色来组成,包括发布者、订阅者和发布订阅中心,其中发布订阅中心是重点。
- 观察者模式实现
- 被观察者对象
class Subject { constructor() { this.observerList = []; } addObserver(observer) { this.observerList.push(observer); } removeObserver(observer) { const index = this.observerList.findIndex(o => o.name === observer.name); this.observerList.splice(index, 1); } notifyObservers(message) { const observers = this.observerList; observers.forEach(observer => observer.notified(message)); } }
- 观察者
class Observer { constructor(name, subject) { this.name = name; if (subject) { subject.addObserver(this); } } notified(message) { console.log(this.name, 'got message', message); } }
- 使用
const subject = new Subject(); const observerA = new Observer('observerA', subject); const observerB = new Observer('observerB'); subject.addObserver(observerB); subject.notifyObservers('Hello from subject'); subject.removeObserver(observerA); subject.notifyObservers('Hello again');
装饰器模式
wip