★观察者模式★
观察者模式
观察者模式也叫做发布-订阅模式,这个设计模式定义了一个1对多的依赖关系。当一个对象的状态发生改变的时候,所有订阅了等等对象都会接到通知
案例-汇率转换
我们要做一个案例,目的就是实现发布-订阅的功能;
我们的人民币是一个发布者,当前只有人民币进行信息的发布,所有的外币,只有接收通知的功能
第一步要设置初始dom
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <title>Document</title> 8 <script src="./jquery-3.2.1.min.js"></script> 9 </head> 10 <body> 11 <div id="box"> 12 </div> 13 </body> 14 <script> 15 // 人民币类 16 function RMB() { 17 // 创建人民币输入框的dom 18 this.$dom = "<div><span>人民币:</span><input type='text'/></div>"; 19 // 追加节点 20 $("#box").append(this.$dom) 21 } 22 // 外币类 23 function ForeignCurrency(title, rate) { 24 this.title = title; //外币名称 25 this.rate = rate; //外币汇率 26 // 外币的dom 27 this.$dom = "<div><span>" + this.title + ":</span><input disabled type='text'/></div>"; 28 $("#box").append(this.$dom) 29 } 30 new RMB() 31 new ForeignCurrency("美元", '2'); 32 new ForeignCurrency("英镑", '3'); 33 new ForeignCurrency("日元", '4'); 34 new ForeignCurrency("欧元", '5'); 35 </script> 36 </html>
发布订阅的核心之一就是自己的事情自己管理
接下来让人民币类,维护一个数组,内部存放的是订阅者列表的信息。然后提供相应的订阅方法subscribe,便于其他的实例进行订阅,让每一个外币在实例化的时候,顺便将自己维护到人民币的数组中
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <title>Document</title> 8 <script src="./jquery-3.2.1.min.js"></script> 9 </head> 10 <body> 11 <div id="box"> 12 </div> 13 </body> 14 <script> 15 // 人民币类 16 function RMB() { 17 // 创建人民币输入框的dom 18 this.$dom = $("<div><span>人民币:</span><input type='text'/></div>"); 19 // 追加节点 20 $("#box").append(this.$dom); 21 // 维护订阅者的数组 22 this.subscribers = []; 23 }; 24 // 注册方法,让每一个外币添加到订阅数组中 25 RMB.prototype.subscribe = function(obj) { 26 this.subscribers.push(obj); 27 //console.log(this.subscribers) //查看维护到数组的外币 28 }; 29 // 外币类 30 function ForeignCurrency(title, rate) { 31 this.title = title; //外币名称 32 this.rate = rate; //外币汇率 33 // 外币的dom 34 this.$dom = $("<div><span>" + this.title + ":</span><input disabled type='text'/></div>"); 35 $("#box").append(this.$dom); 36 // 订阅人民币 37 rmb.subscribe(this) 38 }; 39 var rmb = new RMB(); 40 new ForeignCurrency("美元", '2'); 41 new ForeignCurrency("英镑", '3'); 42 new ForeignCurrency("日元", '4'); 43 new ForeignCurrency("欧元", '5'); 44 </script> 45 </html>
外币写一个listen方法,用来订阅rmb发布的信息,rmb设置监听的事件,作用就是用来发布信息的
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <title>Document</title> 8 <script src="./jquery-3.2.1.min.js"></script> 9 </head> 10 <body> 11 <div id="box"> 12 </div> 13 </body> 14 <script> 15 // 人民币类 16 function RMB() { 17 // 创建人民币输入框的dom 18 this.$dom = $("<div><span>人民币:</span><input type='text'/></div>"); 19 // 追加节点 20 $("#box").append(this.$dom); 21 // 维护订阅者的数组 22 this.subscribers = []; 23 // 初始化监听 24 this.bindEvent() 25 }; 26 // 注册方法,让每一个外币添加到订阅数组中 27 RMB.prototype.subscribe = function(obj) { 28 this.subscribers.push(obj); 29 //console.log(this.subscribers) //查看维护到数组的外币 30 }; 31 // 监听,目的是为了给每一个订阅者发布消息 32 RMB.prototype.bindEvent = function() { 33 // 备份this 34 var self = this; 35 this.$dom.find("input").bind('input', function() { 36 // 发布信息 37 for (var i = 0; i < self.subscribers.length; i++) { 38 // 给每一个订阅者发布消息,发布的内容是rmb实时输入的input的内容 39 self.subscribers[i].listen($(this).val()) 40 } 41 }) 42 }; 43 // 外币类 44 function ForeignCurrency(title, rate) { 45 this.title = title; //外币名称 46 this.rate = rate; //外币汇率 47 // 外币的dom 48 this.$dom = $("<div><span>" + this.title + ":</span><input disabled type='text'/></div>"); 49 $("#box").append(this.$dom); 50 // 订阅人民币 51 rmb.subscribe(this) 52 }; 53 // 收听方法,作用是为了接收rmb发布的消息 54 ForeignCurrency.prototype.listen = function(val) { 55 // 订阅者自己管理自己的汇率 56 var r = val / this.rate; 57 // 将汇率结果换算到自己的dom中 58 this.$dom.find("input").val(r) 59 } 60 var rmb = new RMB(); 61 new ForeignCurrency("美元", '2'); 62 new ForeignCurrency("英镑", '3'); 63 new ForeignCurrency("日元", '4'); 64 new ForeignCurrency("欧元", '5'); 65 </script> 66 </html>