zoukankan      html  css  js  c++  java
  • 设计模式之观察者模式

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

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

    上图:

    总结

    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

  • 相关阅读:
    MongoDB4.0以下版本,同一台电脑安装2个MongoDB服务
    CMake编译Mysql connector C++
    Winsock I/O方法
    查看mysql版本的四种方法(转)
    WorkBench,DELETE 标准语句失败
    Qt 透明对话框 自定义透明度
    QString 分割字符串时产生乱码的问题
    winsock error 相关
    线程的分离状态与结合状态
    Oracle 语法
  • 原文地址:https://www.cnblogs.com/arissy/p/10015190.html
Copyright © 2011-2022 走看看