观察者模式

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

订阅杂志

//发布者对象
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);
}

最新文章

  1. MySQL基础知识和操作(一)
  2. iOS多播放器封装
  3. Java基础学习 -- I/O系统、流
  4. 缓存AsimpleCache -- 解决Android中Sharedpreferences无法存储List数据/ASimpleCache
  5. MapReduce的模式、算法和用例
  6. Linux实验二报告
  7. 《数据结构与算法分析:C语言描述_原书第二版》CH2算法分析_课后习题_部分解答
  8. python学习笔记(Tkinter编程利用Treeview实现表格自动更新)
  9. CI 笔记(1)
  10. socket基础(二)
  11. Result Cache结果高速缓存 (转)
  12. javascript 基础系列(二)
  13. html行内元素,块元素,空元素
  14. Just for mysql
  15. React Native之携程Moles框架
  16. Java的学习05
  17. linux 查看信息-进程&amp;用户&amp;服务&amp;程序
  18. JVM加载class文件的原理机制(转)
  19. nvm(Node Version Manager)管理node版本
  20. iOS-QQ临时对话、QQ群申请跳转

热门文章

  1. IOS-Gesture(手势识别)
  2. mongodb配置文件.conf
  3. vs2013中项目依赖项的作用
  4. jpg Test
  5. 简单的mysql封装类
  6. jQuery - 1.简单的JQuery
  7. jQuery ajax同步的替换方法,使用 $.Deferred()对象
  8. 如何知道SQL语句的性能和改进途径
  9. 攻城狮在路上(壹) Hibernate(八)--- 映射Hibernate组成关系
  10. &lt;转&gt;ORA-06413 连接未打开错误