最近看到了观察者模式的例子,以此记录一下。都是通过代码例子来说明的。如有不对,欢迎指出。
观察者设计模式的原理的例子:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>观察者设计模式的原理</title> </head> <body> <script> // 对象:被观察者(发布者) 某个属性变化 // 观察者(订阅者) 观察某个属性 // 满足某种条件 + 观察者执行相应的响应操作 //可以理解成 观察者观察某个被观察者属性的变化,如果满足某些条件,则观察者执行相应的操作。一个观察者可以观察多个被观察者,一个被观察者可以被多个观察者观察。 var child = {};//被观察者 child.list = [];//观察者的回调函数 //list:[ // 某个属性a:[,这里面是所有监听属性变化的回调函数,只要观察的属性发生变化,监听属性变化的回调函数都会重新执行] //某个属性b:[] // ] //定义 增加观察者 child.listen = function(key,fn) { //看数组中是否有这个属性,如果之前没有人观察这个属性,就默认将该属性添加到需要观察的数组中, if(!this.list[key]){ this.list[key] = []; } //如果之前有人观察这个属性,就将其回调函数添加到数组中 this.list[key].push(fn); } //定义 被观察者 变化 通知观察者 child.change = function(key,value){ //只要属性变化,就执行所有观察者的回调函数 for(var i = 0,fn; fn = this.list[key][i++];) { fn.apply(this,arguments); //fn(key value); } } //增加一个观察者 child.listen('key1',function(key,value){ if(value==40){ console.log(arguments); } }); child.listen('key1',function(){ console.log(arguments); }); //增加一个观察者 child.listen('key2',function(){ //key value console.log(arguments); }); //[key1:[fn1,fn2] //key2:[fn1] // ] child.change('key1',40); child.change('key2',60); </script> </body> </html>
下面的例子进行了一下封装,话不多说上代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>观察者设计模式</title> </head> <body> <script> //被观察者对象 var observer = { list: [], listen: function(key,fn) { if(!this.list[key]) { this.list[key] = []; } this.list[key].push(fn); }, change: function(key,value){ var fns = this.list[key]; if(!fns || fns.length === 0) { return; } //只要属性变化,就执行所有观察者的回调函数 for(var i = 0,fn; fn = fns[i++];) { fn(key,value); } } }; //谁要被观察,谁就继承observer //这段代码实现的是继承 var init = function(obj) { for(var i in observer) {//i相当于属性 obj[i] = observer[i]; } }; var child = {}; init(child); child.listen('age',function (key,value) { if (value==30){ console.log(key+':'+value); } }) child.listen('height',function (key,value) { console.log(key+':'+value); }) child.change('age',20);//不输出 child.change('age',30);//输出age:30 child.change('age',30);//输出age:30 child.change('height',180);//输出height:180 </script> </body> </html>