zoukankan      html  css  js  c++  java
  • javascript优化--12模式(设计模式)03

    观察者模式

    通过创建一个可观察的对象,当发生一个感兴趣的事件时将该事件通告给所有观察者,从而形成松散的耦合

    订阅杂志

    //发布者对象
    var publisher = {
      subscribers: {
        any: [] //事件类型
      },
      //将订阅者添加到subscribers数组;
      subscribe: function(fn, type) {
        type = type || 'any';
        if(typeof this.subscribers[type] === 'undefined') {
          this.subscribers[type] = [];
        }
        this.subscribers[type].push(fn);
      },
      //从订阅者数组中删除订阅者
      unsubscribe: function(fn, type) {
        this.visitSubscribers('publish', publication, type);
      },
      //遍历循环
      publish: function(publication, type) {
        this.visitSubscribers('publish', publication, type);
      },
      visitSubscribers: function(action, arg, type) {
        var pubtype = type || 'any',
        subscribers = this.subscribers[pubtype], i, max = subscribers.length;
        for(i = 0; i < max; i++) {
          if(action === 'publish') {
            subscribers[i](arg);  
          } else {
            if(subscribers[i] === arg) {
              subscribers.splice(i, 1);
            }
          }
        }
      }
    }
    //构造发行者
    function makePublisher(o) {
      var i;
      for(i in publisher) {
        if(publisher.hasOwnProperty(i) && typeof publisher[i] === 'function') {
          o[i] = publisher[i];
        }
      }
      o.subscribers = {any: []};
    }
    //paper对象,发布日刊和月刊
    var paper = {
      daily: function() {
        this.publish("big news today");
      },
      monthly: function() {
        this.publish("interesting analysis", "monthly");
      }
    };
    //订阅者joe
    var joe = {
      drinkCoffee: function(paper) {
        console.log('Just read ' + paper);
      },
      sundayPreNap: function(monthly) {
        console.log('About to fall asleep reading this ' + monthly);
      }
    }
    //将paper构造成一个发行者
    makePublisher(paper);
    //joe订阅paper
    paper.subscribe(joe.drinkCoffee);
    paper.subscribe(joe.sundayPreNap, 'monthly');
    //触发事件
    paper.daily();
    paper.daily();
    paper.daily();
    paper.monthly();
    //扩展将joe为发布者
    makePublisher(joe);
    joe.tweet = function(msg) {
      this.publish(msg);
    }
    paper.readTweets = function(tweet) {
      alert('Call big meeting! Someone ' + tweet);
    }
    joe.subscribe(paper.readTweets);
    
    joe.tweet('hated the paper today');
    
    
    

    按键游戏

    var publisher = {
      subscribers: {
        any: []
      },
      on: function (type, fn, context) {
        type = type || 'any';
        fn = typeof fn === "function" ? fn : context[fn];    
        if (typeof this.subscribers[type] === "undefined") {
          this.subscribers[type] = [];
        }
        this.subscribers[type].push({fn: fn, context: context || this});
      },
      remove: function (type, fn, context) {
        this.visitSubscribers('unsubscribe', type, fn, context);
      },
      fire: function (type, publication) {
        this.visitSubscribers('publish', type, publication);
      },
      visitSubscribers: function (action, type, arg, context) {
        var pubtype = type || 'any',
        subscribers = this.subscribers[pubtype], i,
        max = subscribers ? subscribers.length : 0;
                
        for (i = 0; i < max; i += 1) {
          if (action === 'publish') {
            subscribers[i].fn.call(subscribers[i].context, arg);
          } else {
            if (subscribers[i].fn === arg && subscribers[i].context === context) {
              subscribers.splice(i, 1);
            }
          }
        }
      }
    };
    
    function makePublisher(o) {
      var i;
      for (i in publisher) {
        if (publisher.hasOwnProperty(i) && typeof publisher[i] === "function") {
          o[i] = publisher[i];
        }
      }
      o.subscribers = {any: []};
    }
    
    var game = {  
      keys: {},
      addPlayer: function (player) {
        var key = player.key.toString().charCodeAt(0);
        this.keys[key] = player;
      },
      handleKeypress: function (e) {
        e = e || window.event; // IE
        if (game.keys[e.which]) {
          game.keys[e.which].play();
        }
      },
      handlePlay: function (player) {
        var i, players = this.keys, score = {};
        for (i in players) {
          if (players.hasOwnProperty(i)) {
            score[players[i].name] = players[i].points;
          }
        }
        this.fire('scorechange', score);
      }
    };
    
    function Player(name, key) {
      this.points = 0;
      this.name = name;
      this.key  = key;
      this.fire('newplayer', this);
    }
    
    Player.prototype.play = function () {
      this.points += 1;
      this.fire('play', this);
    };
    
    var scoreboard = {  
      element: document.getElementById('results'),  
      update: function (score) { 
        var i, msg = '';
        for (i in score) {
          if (score.hasOwnProperty(i)) {
              msg += '<p><strong>' + i + '</strong>: ';
              msg += score[i];
              msg += '</p>';
          }
        }
        this.element.innerHTML = msg;
      }
    };
    
    makePublisher(Player.prototype);
    makePublisher(game);
    
    Player.prototype.on("newplayer", "addPlayer", game);
    Player.prototype.on("play",      "handlePlay", game);
    
    game.on("scorechange", scoreboard.update, scoreboard);
    
    window.onkeypress = game.handleKeypress;
    
    var playername, key;
    while (1) {
      playername = prompt("Add player (name)");
      if (!playername) {
        break;
      }
      while (1) {
        key = prompt("Key for " + playername + "?");
        if (key) {
          break;
        }
      }
      new Player(playername,  key);    
    }
    
    
  • 相关阅读:
    iOS开发之Socket
    IOS开发之Bug--使用KVC的易错情况
    IOS开发之功能模块--给任意的UIView添加点击事件
    IOS开发之开发者账号遇到的bug
    iOS开发--关于TableViewCell的可视化设置细节
    学习Coding-iOS开源项目日志(四)
    Learn how to Use UIPageViewController in iOS
    关于Storyboard的使用
    学习Coding-iOS开源项目日志(三)
    学习Coding-iOS开源项目日志(二)
  • 原文地址:https://www.cnblogs.com/jinkspeng/p/4343716.html
Copyright © 2011-2022 走看看