观察者模式

1. 定义

观察者模式   一种对象行为模式。它定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

2.作用   促进形成松散耦合

3.相关实例代码

普通对象实现

    var subject0=function(){
      console.log('subject0');
    }

    var subject1=function(){
      console.log('subject1');
    }

    var observer={
      callbacks:[],
      add:function(subject){
        this.callbacks.push(subject)
      },
      publish:function(){
        this.callbacks.forEach(function(item){
          item()
        })
      }
    }

    observer.add(subject0);
    observer.add(subject1);

    observer.publish();
View Code

class 方式实现

    var subject0=function(){
      console.log('subject0');
    }

    var subject1=function(){
      console.log('subject1');
    }

    class Observer{
      constructor(){
        this.subjects=[]
      }      

      add(subject){
        this.subjects.push(subject)
      }
      publish(){
        this.subjects.forEach(function(item){
          item()
        })
      }
    }

    var observer1=new Observer()
    observer1.add(subject0);
    observer1.add(subject1);

    observer1.publish();
View Code

改造 ajax 实例 前

$.ajax({
  url: "test.html",
  context: document.body
}).done(function(data) {
  //data数据的处理
  $('aaron1').html(data.a)
  $('aaron2').html(data.b)
  $('aaron3').html(data.c)
  //其余处理
});
View Code

改造 ajax 实例 后

Observable.add(function() {
  //pocessData
})

Observable.add(function() {
  $('aaron1').html(data.a)
  $('aaron2').html(data.b)
  $('aaron3').html(data.c)
})

Observable.add(function() {
  //pocessOther
})

$.ajax({
  url: "test.html",
  context: document.body
}).done(function(data) {
  Observable.fire(data)
})
View Code

jQuery工具方法Callbacks详解

带参数与链式调用

class Observer{
    constructor(){
      this.callbacks=[]
    }
    on(name){
      this.callbacks.push(name)
      return this
    }
    emit(...args){
      this.callbacks.forEach(item=>{
        item.apply(null,args)
      })
      return this
    }
    off(name){
      this.callbacks.forEach((item,key)=>{
        if(item===name){
          this.callbacks.splice(key,1)
        }
      })
      return this
    }

  }

  var observer=new Observer();
  var subject1=function(){
    console.log('subject1')
  }
  var subject2=function(...args){
    console.log(args.join(' '))
  }

  observer.on(subject1).on(subject2).off(subject1).emit('1','2','3')
View Code

多条件判断

lass PubSub {
  constructor() {
    this.handles = {};
  }
 
  on(eventType, handle) {
    if (!this.handles.hasOwnProperty(eventType)) {
      this.handles[eventType] = [];
    }
    if (typeof handle == 'function') {
      this.handles[eventType].push(handle);
    } else {
      throw new Error('缺少回调函数');
    }
    return this;
  }

  emit(eventType, ...args) {
    if (this.handles.hasOwnProperty(eventType)) {
      this.handles[eventType].forEach((item, key, arr) => {
        item.apply(null, args);
      })
    } else {
      throw new Error(`"${eventType}"事件未注册`);
    }
    return this;
  }

  off(eventType, handle) {
    if (!this.handles.hasOwnProperty(eventType)) {
      throw new Error(`"${eventType}"事件未注册`);
    } else if (typeof handle != 'function') {
      throw new Error('缺少回调函数');
    } else {
      this.handles[eventType].forEach((item, key, arr) => {
        if (item == handle) {
          arr.splice(key, 1);
        }
      })
    }
    return this; // 实现链式操作
  }
}


let callback = function () {
  console.log('you are so nice');
}

let pubsub = new PubSub();
pubsub.on('namespace', (...args) => {
  console.log(args.join(' '));
}).on('namespace', callback);

pubsub.emit('namespace', '1', '2', '3');
pubsub.off('namespace', callback);
pubsub.emit('namespace', '1', '2');
View Code

传统写法

function Public() {
  this.handlers = {};
}
Public.prototype = {
    on: function(eventType, handler){
        var self = this;
        if(!(eventType in self.handlers)) {
           self.handlers[eventType] = [];
        }
        self.handlers[eventType].push(handler);
        return this;
    },
    emit: function(eventType){
       var self = this;
       var handlerArgs = Array.prototype.slice.call(arguments,1);
       for(var i = 0; i < self.handlers[eventType].length; i++) {
         self.handlers[eventType][i].apply(self,handlerArgs);
       }
       return self;
    },
    off: function(eventType, handler){
        var currentEvent = this.handlers[eventType];
        var len = 0;
        if (currentEvent) {
            len = currentEvent.length;
            for (var i = len - 1; i >= 0; i--){
                if (currentEvent[i] === handler){
                    currentEvent.splice(i, 1);
                }
            }
        }
        return this;
    }
};
 
var Publisher = new Public();
Publisher.on('a', function(data){
    console.log(1 + data);
});
Publisher.on('a', function(data){
    console.log(2 + data);
});
Publisher.emit('a', '我是第1次调用的参数'); 
Publisher.emit('a', '我是第2次调用的参数');
View Code

 

 

 

4. 其他扩展

4.1 单例模式

var getSingle = function(fn){
    var result;
    return function(){
        return result || (result = fn.apply(this, arguments));
    }
};
var createDiv = function(){
    var div = document.createElement('div');
    div.style.width = '100px';
    div.style.height = '100px';
    div.style.background = 'red';
    div.style.marginBottom = '10px';
    document.body.appendChild(div);
    return div;
};
var createSingleDiv = getSingle(createDiv);
createSingleDiv();
createSingleDiv();
createSingleDiv();
View Code

 

posted @ 2019-07-17 12:23  justSmile2  阅读(202)  评论(0编辑  收藏  举报