zoukankan      html  css  js  c++  java
  • 观察者模式

    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
  • 相关阅读:
    Win7 VS2015环境编译Libpng
    VS2013正确设置DLL环境变量目录的方法
    Win7 VS2013环境编译Squirrel 3.0.7
    docker-compose部署redis
    docker-compose部署nginx
    mysql备份
    docker 清理空间
    centos安装docker
    django整合vue
    部署3主3从redis伪集群
  • 原文地址:https://www.cnblogs.com/justSmile2/p/11200236.html
Copyright © 2011-2022 走看看