zoukankan      html  css  js  c++  java
  • javascript发布订阅模式与观察者模式

    设计模式”(Design Pattern)是针对编程中经常出现的、具有共性的问题,所提出的解决方法。著名的《设计模式》一书一共提出了23种模式。

    耦合性: 模块间关联程度的度量。

    发布订阅模式

    它定义了一种对象间一对多的关系,多个订阅者对象将自己的“主题/事件”注册进一个目标对象,当目标对象状态发生改变时,只需要去执行对应订阅者注册的 "主题/事件" 就行了。这是一种松耦合的状态。目标对象不用关心任何订阅者的情况, 只需要发布注册在自己身上的事件就行了。
    订阅者只管注册 目标对象只管发布 互不影响
    代码实现:

    let event = {
        clientList: {},
        listen (key, fn) {
            if (!this.clientList[key]) {
                this.clientList[key] = []
            }
            this.clientList[key].push(fn)   // 订阅的消息添加进缓存列表
        },
        trigger (type, money) {
            let fns = this.clientList[type]
            if (!fns || fns.length === 0) { // 如果没有绑定对应的消息
                return false
            }
            fns.forEach(fn => {
                fn.apply(this, [money])
            })
        }
    }
    // 再定义一个installEvent函数,用于给所有对象动态安装发布-订阅功能
    // 如:另一家售楼处也想要这个功能,就可以调用这个注册了,不用再写多一次这段代码
    let installEvent = obj => {
        for (let i in event) {
            obj[i] = event[i]
        }
    }
    // 给售楼处对象salesOffices动态增加发布-订阅功能
    let salesOffices = {}
    installEvent(salesOffices)
    // 小明订阅信息
    salesOffices.listen('squareMeter88', price => {
        console.log('小明,你看中的88平方的房子,价格=' + price)
    })
    // 小光订阅信息
    salesOffices.listen('squareMeter88', price => {
        console.log('小光,你看中的88平方的房子,价格=' + price)
    })
    // 小红订阅信息
    salesOffices.listen('squareMeter100', price => {
        console.log('小红,你看中的100平方的房子,价格=' + price)
    })
    salesOffices.trigger('squareMeter88', 2000000)
    salesOffices.trigger('squareMeter100', 2500000)
    
    

    观察者模式

    观察者模式与发布订阅最大的区别是订阅者注册的是自己本身,不再是注册 “主题/事件”,当目标对象状态发生改变时,会调用自身的通知方法,从而调用注册在自身的订阅者的更新方法。

    //观察者列表
    function ObserverList(){
      this.observerList = [];
    }
    ObserverList.prototype.add = function( obj ){
      return this.observerList.push( obj );
    };
    ObserverList.prototype.count = function(){
      return this.observerList.length;
    };
    ObserverList.prototype.get = function( index ){
      if( index > -1 && index < this.observerList.length ){
        return this.observerList[ index ];
      }
    };
    ObserverList.prototype.indexOf = function( obj, startIndex ){
      var i = startIndex;
      while( i < this.observerList.length ){
        if( this.observerList[i] === obj ){
          return i;
        }
        i++;
      }
      return -1;
    };
    ObserverList.prototype.removeAt = function( index ){
      this.observerList.splice( index, 1 );
    };
    
    //目标
    function Subject(){
      this.observers = new ObserverList();
    }
    Subject.prototype.addObserver = function( observer ){
      this.observers.add( observer );
    };
    Subject.prototype.removeObserver = function( observer ){
      this.observers.removeAt( this.observers.indexOf( observer, 0 ) );
    };
    Subject.prototype.notify = function( context ){
      var observerCount = this.observers.count();
      for(var i=0; i < observerCount; i++){
        this.observers.get(i).update( context );
      }
    };
    
    //观察者
    function Observer(){
      this.update = function(){
        // ...
      };
    }
    
    

    区别:

    在观察者模式当中,观察者是知道主体对象(Subject)的(你完全可以在调用update的时候,将主体对象传过去),而主体对象也是一直保留对观察者的记录。而发布订阅模式是没有 发布对象和订阅者是通过 事件/主题 通道进行通信,所以它们之间是相互不知道的。
    发布订阅模式实现了更细粒度化的管理,更松耦合。
    观察者模式一般来说是同步的,而发布订阅通过 "事件/主题"队列,一般来说是异步的。
    观察者模式需要在单个应用程序地址空间中实现。另一方面,发布者/订阅者模式更像是跨应用程序模式,这也体现出发布订阅更解耦。

  • 相关阅读:
    如何注册一个ens域名
    storj
    Polygon
    拜占庭容错
    10秒钟完成metamask上任意公链主网添加
    Logistic Regression
    Normal Equations
    神经网络学习笔记 lecture3:The backpropagation learning proccedure
    Three Types of Learning
    Exercise: Logistic Regression and Newton's Method
  • 原文地址:https://www.cnblogs.com/chenlei987/p/10504956.html
Copyright © 2011-2022 走看看