標籤:splay 封裝 引用 win 物件類型 瀏覽器 pre 開發人員 編程
使用設計模式的要訣時把它們看作你編程工具箱中的多種工具,每一種都有一個特定的用途。在嘗試應用設計模式至代碼之前,你首先要熟悉各種現有的設計模式以及每一種所應用的場合(應用了錯誤的工具將導致不必要的麻煩和時間的浪費)。這些章節將協助你來實現這一點。除非你是一個特別老練的JavaScript開發人員,不然,在你開始為應用程式編寫代碼時頭腦是沒有特定的設計模式的。隨著代碼的不斷積累,你將發現需要對代碼進行改變以使日後的開發更易於管理,同時還要對程式碼程式庫中的檔案按照一定的結構和規律進行管理。此過程通常稱為“重構”。通常,就是在開發的此階段要考慮應用特定的設計模式或架構模式至代碼,以簡化後續的開發工作。要謹慎對待那些堅持要在項目啟動時就要在頭腦中保持某個特定的設計模式來開展編碼工作或在開始時就使用某種特定的預建的JavaScript架構的人員。原因是,除非他們是非常有經驗的專業人員,不然,這等同於在能識別出解決問題所需使用的工具之前就直接選用一種全新的沒有使用經驗的工具。
你應該熟練掌握這裡每一章所介紹的設計模式和架構模式,仔細學習每一種模式並領會其使用的方式方法。隨著時間的積累,你會將逐漸識別出代碼所需要應用的特定模式,進而改進代碼的可維護性,並在某種情況下提升效率。
5.1 什麼是設計模式
設計模式時經過嘗試和測試,通過驗證,通過驗證的代碼編寫和組織方法。通過開發人員提供清晰的結構,移除不必要的複雜性,並將大型程式碼程式庫中的不同部分的串連進行解耦 ,使得代碼更易於理解,易於維護。各種設計模式就好比編程工具箱中的各種工具。
介紹23種不同的設計模式,這些模式可劃分為3大類:建立型,結構型和行為型。
5.2 建立型設計模式
建立型設計模式為你描述了用於建立對象的“類”或方法,而不需要你自己直接建立對象。在決定何對象或何種對象的類型才是與你所面對的特定情況和需求最為相關的時,此抽象層給了你以及你的代碼以更高的靈活性。在這裡,我將為你介紹5種建立型設計模式,每種設計模式都配有相應的例子。你會發現這些設計模式對你的代碼非常有用。
5.21 原廠模式
利用原廠模式,可以實現在不指定特定的“類”而建立出對象。在之前的章節,當涉及“類”時,我們需要直接使用JavaScript關鍵字new來建立某特定“類”或子類的執行個體。而利用原廠模式,對象的建立處理過程被予以抽象,使得相對複雜的對象建立處理過程得以封裝於簡單的介面之下,而不需要使用new關鍵字。此抽象意味著,用作建立各執行個體的後台“類”的類型和方法可以隨時被完全替換,而不需要改變介面來適應類的建立。從其他開發人員角度來說,並不需要例會介面底下所發生的變化。如果預知到在將來可能需要作出許多更改,但又不希望必須重寫散步在大量其他代碼中的“類”的執行個體化代碼,則使用原廠模式是很理想的做法。
代碼清單5-1顯示了原廠模式的例子。當中根據Factory 方法的不同輸入參數,實現了基於若干不同的“類”進行對象的執行個體化。
代碼清單5-1 原廠模式
1 //定義一個工廠,它會基於所輸入的內容,使用最適合的“類”來為我們建立出相應的表單域對象 2 var FormFieldFactory={ 3 //makeField方法使用一下2個選項 4 // -type,定義所建立的表單域物件類型,例如text,email或button 5 // -displayText,基於對象的類型,定義表單域的placeholder(預留位置)文本或按鈕上所顯示的文本 6 makeField:function(options){ 7 var options=options ||{}, 8 type=options.type||"text", 9 displayText=options.displayText ||"",10 field;11 //基於所提供的類型使用最適合的“類”來建立對象執行個體12 switch (type){13 case "text":14 field=new TextField(displayText);15 break;16 case "email":17 field=new EmailField(displayText);18 break;19 case "button":20 field=new ButtonField(displayText);21 break;22 //如果不確定,則使用TextField“類”23 default:24 field=new TextField(displayText);25 break;26 }27 return field;28 29 }30 };31 //定義TextField“類”,用於建立<input type="text">表單元素32 function TextField(displayText){33 this.displayText=displayText;34 }35 36 //getElement方法將利用所提供的placeholder文本值來建立一個DOM元素37 TextField.prototype.getElement=function(){38 var textField=document.createElement("input");39 textField.setAttribute("type","text");40 textField.setAttribute("placeholder",this.displayText);41 return textField;42 }43 44 //定義EmailField類,用於建立<input type="email">表單元素45 function EmailField(displayText){46 this.displayText=displayText;47 }48 //getElement方法將利用所提供的placeholder文本值來建立一個DOM元素49 EmailField.prototype.getElement=function(){50 var emailField=document.createElement("input");51 emailField.setAttribute("type","email");52 emailField.setAttribute("placeholder",this.displayText);53 return emailField;54 };55 56 //定義ButtonField“類”,用於建立<button>表單元素57 function ButtonField(displayText){58 this.displayText=displayText;59 }60 //getElement方法將利用所提供的placeholder文本值來建立一個DOM元素61 ButtonField.prototype.getElement=function(){62 var button=document.createElement("button");63 button.setAttribute("type","submit");64 button.innerHTML=this.displayText;65 return button;66 };
代碼清單5-2示範了如何在應用程式中使用代碼清單5-1所建立的工廠。
代碼清單5-2 使用原廠模式
1 //使用工廠來建立一個文本輸入表單域,一個email表單域和一個提交按鈕。請留意我們如何在不需要知道 2 //底層的那些“類”或它們的特定輸入的情況下建立表單域的。FormFieldFactory對該方式進行了抽象 3 var textField=FormFieldFactory.makeField({type:"text",displayText:"Enter the first line of your address"}), 4 emailField=FormFieldFactory.makeField({type:"email",displayText:"Enter your email address"}), 5 buttonField=FormFieldFactory.makeField({type:"button",displayText:"Submit"}); 6 7 //等到瀏覽器的load事件觸發後,把由這三個新建立的對象所表示的DOM元素添加至當前頁面 8 window.addEventListener("load",function(){ 9 var bodyElement=document.body;10 11 //使用每個對象的getElement()方法,獲得對其DOM元素的引用,以將其添加至頁面12 bodyElement.appendChild(textField.getElement());13 bodyElement.appendChild(emailField.getElement());14 bodyElement.appendChild(buttonField.getElement());15 },false);
在需要在代碼的其餘所有部分通過屏蔽較為複雜的對象建立方法來簡化某些特定對象的建立過程時,使用原廠模式最適合不過了。
5.2.2 抽象原廠模式
精通JavaScript--05設計模式:建立型