设计模式--观察者模式(发布订阅模式)

 观察者模式又叫做发布—订阅模式,是我们最常用的设计模式之一。它定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知和更新。
观察者模式提供了一个订阅模型,其中对象订阅事件并在发生时得到通知,这种模式是事件驱动的编程基石,它有利益于良好的面向对象的设计。
       从上面的话语我们可以得知,观察者模式主要动力是促进形成松散耦合(解耦)。
       设计思路:

       首先先声明一个观察者对象

// 注册观察者对象
    var Observer = (function (){
      var Omsg = {};
      return {
      // 注册方法
      regist: function (type, fn){
        if (typeof Omsg[type] === 'undefined') {
          // 同一个信号,可以顺序执行多个事件,所以应该是个数组
          Omsg[type] = [];
          Omsg[type].push(fn);
        } else {
          Omsg[type].push(fn);
        }
      },
      // 发布方法
      fire: function (type, args) {
        if (!Omsg[type]) {
          // 该消息没有被注册,直接返回
          return;
        }
        // 定义消息
        var events = {
          type:type, // 消息类型
          args: args || {} //消息携带的数据
        },
        i = 0,
        len = Omsg[type].length;// 事件队列的长度
        for (; i < len; i++){
          // 依次执行事件序列
          Omsg[type][i].call(this, events);
        }
      },
      // 消除方法
      remove: function (type, fn) {
        // 如果消息队列存在
        if (Omsg[type] instanceof Array) {
          var i = Omsg[type].length - 1;
          for (; i >= 0; i--) {
            (Omsg[type][i] === fn) && Omsg[type].splice(i, 1);
          }
        }
      }
    };
    }());

例如我这里举一个留言板发布的案例:

然后再将各不相干的留言板增加,计数事件注册,当点击发布功能,发出‘issue’信号:

      // 变量声明
      var ipt = document.getElementsByClassName('js-ipt')[0]; // 输入框
      var btn = document.getElementsByClassName('js-btn')[0]; // 发布按钮
      var num = document.getElementsByClassName('js-num')[0]; // 计数
      var info = document.getElementsByClassName('js-info')[0]; // 留言板
      var forbidBtn = document.getElementsByClassName('js-forbid')[0]; //禁止发布按钮


    // 计数事件
    function Counting () {
      var count = Number(num.innerText);
      count++;
      num.innerText = count;
    }

    // 添加留言事件
    function AddMsg (obj) {
      var pEle = document.createElement('p');
      pEle.innerText = obj.args.value;
      info.appendChild(pEle);
    }

    // 改变颜色
    function ChangeColor () {
      let num = Math.round(Math.random()*900000 + 100000);
      info.style.background = '#' + num;
    }

    // 事件注册
    Observer.regist('issue', AddMsg);
    Observer.regist('issue', Counting);
    Observer.regist('issue', ChangeColor);

    // 发布按钮点击
    btn.onclick = function () {
      var value = ipt.value;
      Observer.fire('issue', {value:value});
      ipt.value = '';
    };
    // 禁止留言,移除事件
    forbidBtn.onclick = function () {
      Observer.remove('issue', AddMsg);
      Observer.remove('issue', Counting);
    };

这样一个发布留言案例就完成了。效果图如下(没有写样式,比较丑):

原文地址:https://www.cnblogs.com/xinsir/p/11282978.html