js设计模式-桥接模式

桥接模式定义:桥梁模式的用意是"将抽象化(Abstraction)与实现化(Implementation)脱耦,使得二者可以独立地变化"。这句话有三个关键词,也就是抽象化、实现化和脱耦。

最简单的桥接模式例子:事件监听器

addEvent(element,"click",getResultByIdBridge);
    function getResultByIdBridge(e){
        getById(this.id, function(result){
            //TODO: this is operate result
        });
    }

 

 桥接模式复杂例子:构建XHR连接队列

  1 var asyncRequest = (function(){
  2     
  3     function handleReadyState(o,callback){
  4         var poll = window.setInterval(function(){
  5             if(o && o.readyState ==4){
  6                 window.clearInterval(poll);
  7                 if(callback) callback(o);
  8             }
  9         },50);
 10     }
 11     
 12     var getXHR = function(){
 13         var http;
 14         try{
 15             http = new XMLHttpRequest();
 16             getXHR = function(){
 17                 return new XMLHttpRequest();
 18             };
 19         }catch(e){
 20             var msxml = ["MSXML2.XMLHTTP.3.0","MSXML2.XMLHTTP","Microsoft.XMLHTTP"];
 21             for(var i =0, len = msxml.length;i <len;i++){
 22                 try{
 23                     http = new ActiveXObject(msxml[i]);
 24                     getXHR = function(){
 25                         return new ActiveXObject(msxml[i]);
 26                     };
 27                     break;
 28                 }catch(e){}
 29             }
 30         }
 31         return http;
 32     }
 33     
 34     return function(method,url,callback,postData){
 35         var http = getXHR();
 36         console.log("send url is:" + url);
 37         http.open(method,url,true);
 38         handleReadyState(http,callback);
 39         http.send(postData || null);
 40     }
 41 })();
 42 
 43 Function.prototype.method = function(name,fn){
 44     this.prototype[name] = fn;
 45     return this;
 46 }
 47 
 48 if(!Array.prototype.forEach){
 49     Array.method("forEach",function(fn,thisObj){
 50         var scope = thisObj || window;
 51         for(var i = 0, len = this.length;i<len;i++){
 52             fn.call(scope,this[i],i,this);
 53         }
 54     })
 55 }
 56 
 57 if(!Array.prototype.filter){
 58     Array.method("filter",function(fn,thisObj){
 59         var scope = thisObj || window;
 60         var a  = [];
 61         for(var i = 0 , len = this.length;i<len;i++){
 62             if(fn.call(scope,this[i],i,this)){
 63                 a.push(this[i]);
 64             }
 65         }
 66         return a;
 67     })
 68 }
 69 
 70 
 71 /******************************************/
 72 window.DED = window.DED || {};
 73 DED.util = DED.util || {};
 74 DED.util.Observer = function(){
 75     this.fns = [];
 76 }
 77 DED.util.Observer.prototype = {
 78     subscribe:function(fn){ //签署
 79         this.fns.push(fn);
 80     },
 81     unsubscribe:function(fn){
 82         this.fns = this.fns.filter(function(item){
 83             if(item != fn){
 84                 return item;
 85             }
 86         });
 87     },
 88     fire:function(o){
 89         this.fns.forEach(function(item){
 90             item(o);
 91         });
 92     }
 93 }
 94 
 95 DED.Queue = function(){
 96     this.queue = [];
 97     this.onComplete = new DED.util.Observer();
 98     this.onFailure = new DED.util.Observer();
 99     this.onFlush = new DED.util.Observer();
100     
101     this.retryCount = 3;
102     this.currentRetry = 0;
103     this.paused = false;
104     this.timeout = 5000;
105     this.conn = {};
106     this.timer = {};
107 };
108 
109 DED.Queue.method("flush",function(){
110     if(!this.queue.length >0){
111         return ;
112     }
113     if(this.paused){
114         this.paused = false;
115         return;
116     }
117     
118     var that = this;
119     this.currentRetry++;
120     var abort = function(){
121         that.conn.abort();
122         if(that.currentRetry == that.retryCount){
123             that.onFailure.fire();
124             that.currentRetry = 0;
125         }else{
126             that.flush();
127         }
128     };
129     
130     this.timer = window.setTimeout(abort,this.timeout);
131     var callback = function(o){
132         window.clearTimeout(that.timer);
133         that.currentRetry = 0;
134         that.queue.shift();
135         that.onFlush.fire(o.responseText);
136         if(that.queue.length == 0){
137             that.onComplete.fire();
138             return;
139         }
140         that.flush();
141     };
142     
143     this.conn = asyncRequest(this.queue[0]["method"],this.queue[0]["url"],callback,this.queue[0]["params"]);
144     }).
145     method("setRetryCount",function(count){
146         this.retryCount = count;
147     }).
148     method("setTimeout",function(time){
149         this.timeout = time;
150     }).
151     method("add",function(o){
152         this.queue.push(o);
153     }).
154     method("pause",function(){
155         this.paused = true;
156     }).
157     method("dequeue",function(){
158         this.queue.pop();
159     }).
160     method("clear",function(){
161         this.queue = [];
162     });
View Code

 

对应的html

  1 <!DOCTYPE html>
  2 <html>
  3     <head>
  4         <meta charset="UTF-8">
  5         <title></title>
  6         <style type="text/css">
  7             body{font:100% georgia,times,serif}
  8             h1,h2{font-weight: normal;}
  9             #queue-items{height:1.5rem;}
 10             #add-stuff{padding:0.5rem; background:#ddd; border:1px solid #bbb;}
 11             #result-area{padding:0.5rem; border: 1px solid #bbb;}
 12         </style>
 13     </head>
 14     <body id="exmapl">
 15         <div id="doc">
 16             <h1>Ajax Conection Queue</h1>
 17             <div id="queue-items"></div>
 18             <div id="add-stuff">
 19                 <h2>Add Requests to Queue</h2>
 20                 <ul id="adders">
 21                     <li><a href="#" id="action-01">add 01 to Queue</a></li>
 22                     <li><a href="#" id="action-02">add 02 to Queue</a></li>
 23                     <li><a href="#" id="action-03">add 03 to Queue</a></li>
 24                     <li><a href="#" id="action-04">add 04 to Queue</a></li>
 25                 </ul>
 26             </div>
 27             <h2>oTther Queue actions</h2>
 28             <ul id="items">
 29                 <li><a href="#" id="flush">Flush</a></li>
 30                 <li><a href="#" id="dequeue">dequeue</a></li>
 31                 <li><a href="#" id="pause">pause</a></li>
 32                 <li><a href="#" id="clear">clear</a></li>
 33             </ul>
 34             
 35             <div id="result-area">
 36                 <h2>Results:</h2>
 37                 <div id="results"></div>
 38             </div>
 39         </div>
 40     </body>
 41 </html>
 42 <script type="text/javascript" src="Bridge.js"></script>
 43 <script>
 44     window.onload = function(){
 45         var q = new DED.Queue();
 46         q.setRetryCount(5);
 47         q.setTimeout(3000);
 48         
 49         
 50         var items = document.getElementById("items");
 51         var queue = document.getElementById("queue-items");
 52         var requests = [];
 53         q.onFlush.subscribe(function(data){
 54             results.innerHTML = data;
 55             requests.shift();
 56             queue.innerHTML = requests.toString();
 57         });
 58         q.onFailure.subscribe(function(){
 59             results.innerHTML += "<span style='color:red;'>Connection error</span>";
 60         });
 61         
 62         q.onComplete.subscribe(function(){
 63             results.innerHTML += "<span style='color:green;'>Completed!</span>";
 64         });
 65         
 66         var actionDispatcher = function(element){
 67             switch(element){
 68                 case "flush":
 69                     q.flush();
 70                     break;
 71                 case "dequeue":
 72                     requests.pop();
 73                     queue.innerHTML = requests.toString();
 74                     break;
 75                 case "pause":
 76                     q.pause();
 77                     break;
 78                 case "clear":
 79                     q.clear();
 80                     requests = [];
 81                     queue.innerHTML = "";
 82                     break;
 83             }
 84         };
 85         
 86         var addRequest = function(request){
 87             var data = request.split("-")[1];
 88             q.add({
 89                 method:"GET",
 90                 url:"http://127.0.0.1:8020/WS_WEB/JS%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/js/ajax.json?data=" + data,
 91                 params:null
 92             });
 93             requests.push(data);
 94             queue.innerHTML = requests.toString();
 95         };
 96         
 97         items.onclick = function(e){
 98             var e = e || window.event;
 99             var src = e.target || e.srcElement;
100             try{
101                 e.preventDefault();
102             }catch(e){
103                 e.returnValue = false;
104             }
105             if(src.id){
106                 actionDispatcher(src.id);
107             }
108         };
109         
110         var adders = document.getElementById("adders");
111         adders.onclick = function(){
112             var e = e || window.event;
113             var src = e.target || e.srcElement;
114             if(e.preventDefault){
115                 e.preventDefault();
116             }else{
117                 e.returnValue = false;
118             }
119             if(src.id)addRequest(src.id);
120         }
121         
122     }
123     
124 </script>

 

posted @ 2016-04-02 19:13  Tengri  阅读(381)  评论(0编辑  收藏  举报