zoukankan      html  css  js  c++  java
  • 设计模式--观察者模式(发布订阅模式)

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

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

    // 注册观察者对象
        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);
        };

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

  • 相关阅读:
    10、驱动中的阻塞与非阻塞IO
    8、Linux设备驱动的并发控制
    入职一个月考核学习
    5、映射的思考
    6、udev机制
    7、字符设备系统
    linux 内存管理之kmalloc、vmalloc、malloc、get_gree_pages的区别
    嵌入式笔试题(linux基础)
    驱动总结
    系统移植总结
  • 原文地址:https://www.cnblogs.com/xinsir/p/11282978.html
Copyright © 2011-2022 走看看