列举

创建型

  • 要点
    • 提供创建对象的机制, 能够提升已有代码的灵活性和可复用性。
  • 工厂方法
  • 抽象工厂
  • 生成器
  • 原型
  • 单例

结构型

  • 要点
    • 考虑的是对象的组成和对象之间的关系,假如对象发生了重大改变,对当前对象操作影响降至最低
    • 将对象和类组装成较大的结构, 并同时保持结构的灵活和高效。
  • 适配器模式
  • 桥接模式
  • 组合
  • 装饰器模式
  • 外观模式
  • 享元模式
  • 代理模式

行为型

  • 要点
    • 关注的是对象之间的依赖关系以及通信
    • 负责对象间的高效沟通和职责委派。
  • 责任链
  • 命令
  • 迭代器
  • 中介者
  • 备忘录
  • 观察者
  • 状态
  • 策略
  • 模板方法
  • 访问者

前端常用

  1. 单例模式
  2. 观察者模式(发布订阅模式)
    • redux
  3. 命令模式
    • s3
  4. 策略模式
    • 大幅度减少多重条件下的判断

有助于提高系统的可拓展性

  • 工厂模式
  • 抽象工厂模式
  • 观察者模式: 观察者很容易增加
  • 适配器模式: 适配新的接口
  • 代理模式: 在原来的功能上增加新功能或逻辑
  • 责任链模式: 通过新增拦截器/过滤器来实现对数据的处理
  • 策略模式: 新增策略

发布订阅

定义

  • 发布-订阅模式其实是一种对象间一对多的依赖关系。
  • 当一个对象的状态发送改变时,所有依赖于它的对象都将得到状态改变的通知。
  • 三个角色(订阅者,调度中心,发布者)
  • 流程:订阅者(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

区别于观察者模式

  • 观察者是经典软件设计模式中的一种,但发布订阅只是软件架构中的一种消息范式。
  • 观察者模式本身只需要2个角色便可成型,即观察者和被观察者,其中被观察者是重点。
  • 发布订阅需要至少3个角色来组成,包括发布者、订阅者和发布订阅中心,其中发布订阅中心是重点。
  • 观察者模式实现
    1. 被观察者对象
    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));
    }
    
    }
    
    1. 观察者
    class Observer {
    
    constructor(name, subject) {
        this.name = name;
        if (subject) {
        subject.addObserver(this);
        }
    }
    
    notified(message) {
        console.log(this.name, 'got message', message);
    }
    
    }
    
    1. 使用
    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');
    

参考