• javascript观察者模式


    观察者模式又称发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。

    观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听一个主题对象。这个主题对象在状态上发生变化时,会通知所有观察者,使它们能够自动更新自己。

    下面拿老外的例子改一改,练练手。

     
         var dom = {
            each : function(obj,fn,score){
              for(var key in obj){
                if(obj.hasOwnProperty(key))
                  fn.call(score,obj[key],key,obj)
              }
            }
          };
          dom.each({
            indexOf: function (el, index) {
              var n = this.length,
              i = index == null ? 0 : index < 0 ? Math.max(0, n + index) : index;
              for (; i < n; i++)
                if (i in this && this[i] === el) return i;
              return -1;
            },
            //移除 Array 对象中指定位置的元素。
            removeAt: function (index) {
              return this.splice(index, 1)
            },
            //移除 Array 对象中某个元素的第一个匹配项。
            remove: function (item) {
              var index = this.indexOf(item);
              if (index !== -1) this.removeAt(index);
              return item;
            }
          },function(method,name){
            if(!Array.prototype[name])
              Array.prototype[name] = method;
          });
    
          /* 订阅者接口 */
          var Observer = function() {
            //观察者要实现的方法
            this.update = function() {throw "此方法必须被实现!"}
          }
          /* 发布者接口 */
          var Subject = function() {
            this.observers = [];
          }
          Subject.prototype = {
            //如果状态发生改变,通知所有观察者调用其update方法
            notifyObservers : function(context) {
              for(var i = 0, n = this.observers.length; i < n; i++) {
                this.observers[i].update(context);
              }
            },
            // 添加订阅者
            attach : function(observer){
              if(!observer.update) throw 'Wrong observer';
              this.observers.push(observer);
            },
            /* 移除订阅者 */
            detach : function(observer) {
              if(!observer.update) { throw 'Wrong observer'; }
              this.observers.remove(observer);
            }
          }
          //实现接口
          var implement = function(Concrete,Interface){
            for(var prop in  Interface) {
              Concrete[prop] = Interface[prop];
            }
          }
    
    
          /***************** 发布者的实现类 ***********************/
          var mainCheck = document.createElement("input");
          mainCheck.type = 'checkbox';
          mainCheck.id = 'MainCheck';
          mainCheck.style.cssText = 'border:1px solid red';
          implement( mainCheck,new Subject());
          /* 当点击按钮的时候 给相关的观察者发送通知. 观察者接收到通知的时候 改变状态 */
          mainCheck['onclick'] = function(){
            this.notifyObservers(this.checked)
          }
        
          document.body.appendChild(mainCheck);
    
          /********************* 订阅者的实现类 *****************************/
          var obsCheck1 = document.createElement('input');
          var obsCheck2 = document.createElement('input');
          obsCheck1.type = 'checkbox';
          obsCheck1.id = 'Obs1';
          document.body.appendChild(obsCheck1);
    
          obsCheck2.type = 'checkbox';
          obsCheck2.id = 'Obs2';
          document.body.appendChild(obsCheck2);
          implement( obsCheck1,new Observer());
          implement( obsCheck2,new Observer());
    
          /* 必须实现它们的具体update方法 */
          obsCheck1.update = function(value) {
            this.checked = value;
          }
    
          obsCheck2.update = function(value) {
            this.checked = value;
          }
    
          // 将发布者和订阅者(观察者)关联
          mainCheck.attach(obsCheck1);
          mainCheck.attach(obsCheck2);
    

    这东西比较简单,涉及两个阵营。一个是发布者,你把它当成服务器端就是,肯定要做比客户端更多的事。为此,发布者要拥有订阅者的列表,支持添加或删除它们,当自己更新时,同步更新订阅者相应的东西。订阅者则不需要做许多事,只要提供一个update方法,供发布者调用就是。写这个时,我总是想起RSS,我的博客更新,便立即更新订阅者google reader上的内容。不过,javascript拥有DOM过门的事件系统,除非涉及的几个对象都不是元素节点,一般很少自己重新造轮子。

    注:本文为rightjs学习笔记的一部分。

  • 相关阅读:
    第五十四天:jQuery内容的基础:
    第五十三天dom基础
    第五十二天js的&#183;进阶
    第五十一天js的基础
    第四十九天css进阶
    第四十八天 html中的form和css基础
    第四十七天:web中德html初级:
    第42天IO模块
    第四十一天:协程操作
    第四十天线程的进阶
  • 原文地址:https://www.cnblogs.com/rubylouvre/p/1699203.html
Copyright © 2020-2023  润新知