zoukankan      html  css  js  c++  java
  • js之观察者模式和发布订阅模式区别

    观察者模式(Observer)

    观察者模式指的是一个对象(Subject)维持一系列依赖于它的对象(Observer),当有关状态发生变更时 Subject 对象则通知一系列 Observer 对象进行更新。

    在观察者模式中,Subject 对象拥有添加、删除和通知一系列 Observer 的方法等等,而 Observer 对象拥有更新方法等等。

    在 Subject 对象添加了一系列 Observer 对象之后,Subject 对象则维持着这一系列 Observer 对象,当有关状态发生变更时 Subject 对象则会通知这一系列 Observer 对象进行更新。

    function Subject(){
      this.observers = [];
    }
    
    Subject.prototype = {
      add:function(observer){  // 添加
        this.observers.push(observer);
      },
      remove:function(observer){  // 删除
        var observers = this.observers;
        for(var i = 0;i < observers.length;i++){
          if(observers[i] === observer){
            observers.splice(i,1);
          }
        }
      },
      notify:function(){  // 通知
        var observers = this.observers;
        for(var i = 0;i < observers.length;i++){
          observers[i].update();
        }
      }
    }
    
    function Observer(name){
      this.name = name;
    }
    
    Observer.prototype = {
      update:function(){  // 更新
        console.log('my name is '+this.name);
      }
    }
    
    var sub = new Subject();
    
    var obs1 = new Observer('ttsy1');
    var obs2 = new Observer('ttsy2');
    
    sub.add(obs1);
    sub.add(obs2);
    sub.notify();  //my name is ttsy1、my name is ttsy2
    

      

    上述代码中,我们创建了 Subject 对象和两个 Observer 对象,当有关状态发生变更时则通过 Subject 对象的 notify 方法通知这两个 Observer 对象,这两个 Observer 对象通过 update 方法进行更新。

    在 Subject 对象添加了一系列 Observer 对象之后,还可以通过 remove 方法移除某个 Observer 对象对它的依赖。


    var sub = new Subject();
    
    var obs1 = new Observer('ttsy1');
    var obs2 = new Observer('ttsy2');
    
    sub.add(obs1);
    sub.add(obs2);
    sub.remove(obs2);
    sub.notify();  //my name is ttsy1
    

      

    发布订阅模式(Publisher && Subscriber)

    发布订阅模式指的是希望接收通知的对象(Subscriber)基于一个主题通过自定义事件订阅主题,被激活事件的对象(Publisher)通过发布主题事件的方式通知各个订阅该主题的 Subscriber 对象。


    let pubSub = {
      list:{},
      subscribe:function(key,fn){  // 订阅
        if (!this.list[key]) {
          this.list[key] = [];
        }
        this.list[key].push(fn);
      },
      publish:function(){  // 发布
        let arg = arguments;
        let key = [].shift.call(arg);
        let fns = this.list[key];
    
        if(!fns || fns.length<=0) return false;
    
        for(var i=0,len=fns.length;i<len;i++){
          fns[i].apply(this, arg);
        }
    
      },
      unSubscribe(key) {  // 取消订阅
        delete this.list[key];
      }
    };
    
    pubSub.subscribe('name', (name) => {
      console.log('your name is ' + name);
    });
    pubSub.subscribe('sex', (sex) => {
      console.log('your sex is ' + sex);
    });
    pubSub.publish('name', 'ttsy1');  // your name is ttsy1
    pubSub.publish('sex', 'male');  // your sex is male
    

      

    上述代码的订阅是基于 name 和 sex 主题来自定义事件,发布是通过 name 和 sex 主题并传入自定义事件的参数,最终触发了特定主题的自定义事件。

    可以通过 unSubscribe 方法取消特定主题的订阅。

    pubSub.subscribe('name', (name) => {

    pubSub.subscribe('name', (name) => {
      console.log('your name is ' + name);
    });
    pubSub.subscribe('sex', (sex) => {
      console.log('your sex is ' + sex);
    });
    pubSub.unSubscribe('name');
    pubSub.publish('name', 'ttsy1');  // 这个主题被取消订阅了
    pubSub.publish('sex', 'male');  // your sex is male
    

      

    观察者模式 VS 发布订阅模式

    观察者模式与发布订阅模式都是定义了一个一对多的依赖关系,当有关状态发生变更时则执行相应的更新。

    不同的是,在观察者模式中依赖于 Subject 对象的一系列 Observer 对象在被通知之后只能执行同一个特定的更新方法,而在发布订阅模式中则可以基于不同的主题去执行不同的自定义事件。相对而言,发布订阅模式比观察者模式要更加灵活多变。

    我认为,观察者模式和发布订阅模式本质上的思想是一样的,而发布订阅模式可以被看作是观察者模式的一个进阶版。

    设计模式只是一种思想,某一种设计模式都可以有很多种不同的实现方式,各种实现都有其优劣之分,具体的实现方式需要基于不同的业务场景。上述是我对观察者模式和发布订阅模式学习之后的一些理解,望指正。



  • 相关阅读:
    Sublime Text3 python自动补全问题——Sublime Text3安装Anaconda插件
    微信小程序如何刷新当前界面
    No 'Access-Control-Allow-Origin' header is present on the requested resource——Web Api跨域问题
    云时代架构阅读笔记四——线程池是如何使我们的应用变快的?
    jQuery实现图片放大镜效果
    云时代架构阅读笔记三——架构师比程序员厉害在哪里?
    Ajax学习系列——jQuery中Ajax的请求方式
    读书笔记:梯度是怎么消失的
    读书笔记:初始化神经网络
    读书笔记:对抗过拟合
  • 原文地址:https://www.cnblogs.com/yongwunaci/p/12021194.html
Copyright © 2011-2022 走看看