前一段時間由於清明節,女朋友來中國,所以陪人家玩了幾天,就沒看書,有些荒廢了,這幾天補上吧.接下來我們會討論一下javascript設計模式之工程模式,這篇之後,可能對於javascript設計模式的探究會告一段落,接下來還是再多學一下javascript的一些基礎知識,再鞏固一下.prototype(原型鏈),function,範圍鏈,javascript操作dom,bom,變數對象,this.ajax等等,還可能看看html5,css,既然選擇了走web前端這條路,那就堅持吧,是金子總會發光的.好了,回到正題:原廠模式
原廠模式適用場合:
1.動態實現--需要建立一些用不同方式實現同一介面的對象
2.節省設定開銷--對象需要進行複雜並且彼此相關的設定
3.小型對象組成一個大對象--建立封裝許多較小對象的對象.
執行個體:
還是看例子說話吧,個人覺得原廠模式就是switch(很膚淺),就是將一些不同方式實現同一介面的方法封裝成一個對象.
View Code
/* AjaxHandler interface */var AjaxHandler = new Interface('AjaxHandler',['request','createXhrObject']);/* SimpleHandler class */var SimpleHandler = function(){}; //implements AjaxHandlerSimpleHandler.prototype ={ request:function(method,url,callback,postVars){ var xhr = this.createXhrObject(); xhr.onreadystatechange = function(){ if(xhr.readyState !== 4)return; (xhr.status === 200)? callback.success(xhr.responseText,xhr.responseXML): callback.failure(xhr.status); }; xhr.open(method,url,true); if(method !=='POST') postVars = null; xhr.send(postVars); }, createXhrObject:function(){ //Factory method. var methods = [ function(){return new XMLHttpRequest();}, function(){return new ActiveXObject('Msxml2.XMLHTTP');}, funtion(){return new ActiveXObject('Microsoft.XMLHTTP');} ]; for(var i = 0,len = method.length;i<len;i++){ try{ methods[i](); } catch(e){ continue; } //if we reach this point,method[i] worked. this.createXhrObject = method[i]; //Memoize the method. return methods[i]; } //If we reach this point, none of the methods worked. throw new Error('SimpleHandler:Could not create an XHR object.'); }};
這個例子中request負責執行發出請求和處理響應結果所需的一系列操作,它先建立一個XHR對象並對其進行配置,然後再發送請求.
這個例子可以進一步擴充,把原廠模式用在兩個地方,以便根據網路條件建立專門的請求對象.在建立XHR對象時已經用過了簡單原廠模式,另一個工廠則用來返回各種處理器類.首先建立兩個新的處理器類,QueuedHandler會在發起新的請求之前確保所有請求都已經成功處理,而OfflineHandler則會在使用者處於離線狀態時把請求緩衝起來。
View Code
/*QueuedHandler Class */var QueuedHandler = function(){// implements ajaxHandler this.queue = []; this.requestInProgress = false; this.retryDelay =5; //in seconds};extend(QueuedHandler, SimpleHandler);QueueHandler.prototype.request = function(method,url,callback,postVars,override){ if(this.requestInProgress && !override){ this.queue.push({ method:method, url:url, callback:callback, postVars:postVars }); } else{ this.reuqestInProgress = true; var xhr = this.createXhrObject(); var that = this; xhr.onreadystatechange = function(){ if(xhr.readyState !== 4)return; if(xhr.status == 200){ callback.success(xhr.responseText,xhr.responseXML); that.advanceQueue(); } else{ callback.failure(xhr.status); setTimeout(function(){ that.request(method,url,callback,postVars,true);}, that.retryDelay*1000); } }; xhr.open(method,url,true); if(method!=='POST')postVars = null; xhr.send(postVars); }};QueuedHandle.prototype.advanceQueue =funtion(){ if(this.queue.length === 0){ this.requestInProgress = false; return; } var req = this.queue.shift(); this.request(req.method,req.url,req.callback,req.postVars,true);};View Code
/* offlineHandler class */var OfflineHandler = function(){ //implements AjaxHandler this.storedRequests = [];};extend(OfflineHandler,SimpleHandler);OfflineHandler.prototype.request = function(method,url,callback,postVars){ if(XhrManager.isOffline()){//Sotre the requests until we are online. this.storedRequest.push({ method:method, url:url, callback:callback, postVars:postVars }); } else{ //call simpleHandler's request method if we are online. this.flushStoredReuqests(); OfflineHandler.superclass.request(method,url,callback,postVars); }};OfflineHandler.prototype.flushStoredReuqests = function(){ for(var i = 0,len = storedRequests.length;i<len;i++){ var req = storedRequests[i]; OfflineHandler.superclass.request(req.method,req.url,req.callback,req.postVars); }};
現在該用到原廠模式了,因為程式員根本不可能知道各個終端使用者實際面臨的網路條件,所以不可能要求他們在開發過程中選擇使用哪個處理器類,而是應該有一個工廠在運行時選擇最合適的類。
View Code
/* XhrManager singleton */var XhrManager = { createXhrHandler:function(){ var xhr; if(this.isOffline()){ xhr = new OfflineHandler(); } else if(this.isHighLatency()){ xhr = new QueuedHanler(); } else{ xhr = new SimpleHandler(); } Interface.ensureImplements(xhr,AjaxHandler); return xhr; }, isOffline:function(){ }, isHighLatency:function(){ }};var myHandler = XhrManager.createXhrHandler();var callback = { success:function(responseText){alert('Success:'+responseText);}, failure:function(stateCode){alert('Failure:'+statusCode);}};myHandler.request('GET','script.php',callback);
使用原廠模式的主要好處在於消除對象間的耦合,通過使用Factory 方法而不是new關鍵字及其具體類,你可以把所有執行個體化代碼集中在一個位置,這可以大大簡化更換所用的類或在運行期間動態選擇所用的類的工作,在派生子類時它也提供了更大的靈活性。使用原廠模式,你可以先建立一個抽象的父類,然後再子類中建立Factory 方法,從而把成員對象的執行個體化延遲到更專門化的子類中進行。
原廠模式雖然好,但是也不能濫用。
寫的很簡單,就不發表了。。接下來還是先看看基礎的javascript文法方面的知識,鞏固一下吧。