JavaScript设计模式-22.观察者模式

  1 <!DOCTYPE html>
  2 <html>
  3     <head>
  4         <meta charset="UTF-8">
  5         <title>javascript高级语法22-观察者模式</title>
  6     </head>
  7     <body onload="init()">
  8         <div id="box"></div>
  9         <script>
 10             //扩展函数  forEach和filter
 11             
 12             Function.prototype.method = function(name, fn) {
 13               this.prototype[name] = fn;
 14               return this;
 15             };
 16             if (!Array.prototype.forEach) { 
 17               Array.method('forEach', function(fn, thisObj) {
 18                 var scope = thisObj || window;
 19                 for ( var i = 0;len < this.length; ++i ) {
 20                    //这样写不是简单的函数调用,是在函数调用的同事把this重新定位
 21                    fn.call(scope, this[i], i, this);
 22                 }
 23               });
 24             }
 25             //Array过滤器
 26             if (!Array.prototype.filter ) {
 27               Array.method('filter', function(fn, thisObj) {
 28                 var scope = thisObj || window;
 29                 var a = [];
 30                 for ( var i = 0;len < this.length; ++i ) {
 31                       //看看过滤函数,真留下来,假的删除
 32                       if ( !fn.call(scope, this[i], i, this) ) {
 33                            continue;
 34                       }
 35                       a.push(this[i]);
 36                 }
 37                 //返回新的数组
 38                 return a;
 39               });
 40             }
 41             
 42             /*观察者模式:
 43              * 分为两个角色:观察者和被观察者
 44              * 观察者模式的目的在于对程序的内在变化进行观察,当其有变化的时候可以得知,并作出相应反应
 45              */
 46             
 47             /*模拟订阅者和报社之间的关系
 48              *实际操作分为(推模式,拿模式)
 49              * 推送->长链接技术
 50              * 拿模式->定时去后台取得
 51             */
 52             
 53             function BusinessOne(name){
 54                 this.name = name;
 55                 //订阅者集合
 56                 this.subscribers = new Array();
 57             }
 58             //订阅者的发送消息的方法(推模式)
 59             BusinessOne.prototype.delive = function(news){
 60                 var self = this;
 61                 //给每一个订阅者发送消息
 62                 this.subscribers.forEach(function(fn){
 63                     //调用接收者处理信息的函数
 64                     fn(news,self);
 65                 })
 66             }
 67             //扩展公共订阅的函数和取消订阅的函数
 68             Function.prototype.subscribe = function(publisher){
 69                 var that = this;
 70                 //some访问数组对象,并且以参数的形式传回回调函数
 71                 //至少有一次返回是true的  那么some就是真
 72                 var alreadyExist = publisher.subscribers.some(
 73                     function(el){
 74                         //处理不能重复订阅的功能
 75                         if(el == that){
 76                             return;
 77                         }
 78                     }
 79                 );
 80                 //没有订阅就可以订阅
 81                 if(!alreadyExist){
 82                     publisher.subscribers.push(that);
 83                 }
 84                 return this;
 85             }
 86             //取消
 87             Function.prototype.unsubscribe = function(publisher){
 88                 var that = this;
 89                 publisher.subscribers = publisher.subscribers.filter(
 90                     function(el){
 91                         if(el !== that){
 92                             return el;
 93                         }
 94                     }
 95                 );
 96                 return this;
 97             }
 98             
 99             //创建发布者的实例
100             var b1 = new BusinessOne("CCTV");
101             var b2 = new BusinessOne("中国国防部");
102             
103             //发布(门面模式)
104             function addEventFacada(el,type,fn){
105                 if(window.addEventListener){
106                     //firefox
107                     el.addEventListener(type,fn,false);
108                 }else if(window.attachEvent){
109                     //IE
110                     el.attachEvent("on"+type,fn);
111                 }else{
112                     el["on"+type] = fn;
113                 }
114             }
115             //主应用函数
116             var init = function(){
117                 //创建观察者
118                 var pageOne = function(news){
119                     document.getElementById("info").value = 
120                         "我发现了: "+"["+arguments[1].name +"] 发来的信息 --->"+news;
121                 }
122                 //订阅
123                 pageOne.subscribe(b1).subscribe(b2);
124                 //增加绑定事件
125                 addEventFacada(document.getElementById("cctv"),"click",function(){
126                     b1.delive(document.getElementById("cctvText").value);
127                 });
128                 addEventFacada(document.getElementById("gfb"),"click",function(){
129                     b2.delive(document.getElementById("gfbText").value);
130                 });
131             }
132         </script>
133         
134         <input type="text"  id="cctvText"/>
135         <input type="button" value='cctv发送' id="cctv"/>
136         <br />
137         <input type="text"  id="gfbText"/>
138         <input type="button" value='国防部发送' id="gfb"/>
139         <br />
140         <textarea id="info" cols="60" rows="20"></textarea>
141             
142     </body>
143 </html>

 

posted @ 2017-07-16 21:14  橙云生  阅读(199)  评论(0编辑  收藏  举报