• 设计模式之观察者模式


    观察者模式,又被称为发布-订阅模式或消息机制,定义了一种依赖关系,解决了主体对象与观察者之间功能耦合。

    虽然说观察者模式,又被称为发布-订阅模式,但是实际上它们之间存在差异的,区别在于调度的地方不同。

    上图:

    总结

    1. 从两张图片可以看到,最大的区别是调度的地方。虽然两种模式都存在订阅者和发布者(具体观察者可认为是订阅者、具体目标可认为是发布者),但是观察者模式是由具体目标调度的,而发布/订阅模式是统一由调度中心调的,所以观察者模式的订阅者与发布者之间是存在依赖的,而发布/订阅模式则不会。

    2. 两种模式都可以用于松散耦合,改进代码管理和潜在的复用。

    代码

    观察者模式实现代码

    class ObserverList {
      constructor() {
        this.observerList = [];
      }
      add(observer) {
        // todo add observer to list
        return this.observerList.push(observer);
      }
      remove(observer) {
        // todo remove observer from list
        this.observerList = this.observerList.filter(item => item != observer);
    
      }
      count() {
        // return observer list size
        return this.observerList.length;
      }
      get(index) {
        return this.observerList[index];
      }
    }
    
    class Subject {
      constructor() {
        this.observers = new ObserverList();
      }
      addObserver(observer) {
        // todo add observer
        this.observers.add(observer);
      }
      removeObserver(observer) {
        // todo remove observer
        this.observers.remove(observer);
      }
      notify(...args) {
        // todo notify
        let observerCount = this.observers.count();
        for(let i=0; i<observerCount; i++) {
          this.observers.get(i).update(...args);
        }
      }
    }
    
    module.exports = { Subject };
    

    发布订阅实现代码

    module.exports = class PubSub {
    
      constructor() {
        this.subscribers = {};
      }
    
      subscribe(type, fn) {
        // todo subscribe
        if(typeof this.subscribers[type] === 'undefined') {
          this.subscribers[type] = [fn];
        } else {
          this.subscribers[type].push(fn);
        }
      }
    
      unsubscribe(type, fn) {
        // todo unsubscribe
        let listener = this.subscribers[type];
        if(!listener) {
          return;
        }
        this.subscribers[type] = listener.filter(item => item != fn);
    
      }
    
      publish(type, ...args) {
        // todo publish
        let listener = this.subscribers[type];
        if(!listener) {
          return;
        }
        listener.forEach(element => {
          element.call(this, ...args);
        });
      }
    
    }
    

    参考文章

    http://www.cnblogs.com/lovesong/p/5272752.html

  • 相关阅读:
    开放就像死亡访问之后就能回头——Leo鉴书84
    将博客搬至CSDN
    将博客搬至CSDN
    滚动条
    Perl Pack写的一个数据报表程序
    利用hash 数组打印标题
    Linux显示只显示目录文件
    Linux显示按文件名降序文件
    Linux显示以时间生升序显示文件
    Linux显示按文件大小降序排列
  • 原文地址:https://www.cnblogs.com/arissy/p/10015190.html
Copyright © 2020-2023  润新知