本文首發於知乎專欄:前端指南前端
工廠模式定義建立對象的接口,可是讓子類決定實例化哪一個類。工廠方法將類的實例化延遲到子類。node
咱們可使用Object構造函數來建立單個對象,可是,使用同一個接口建立不少對象時,會產生大量重複的代碼。爲了解決這個問題,咱們可使用工廠模式。jquery
咱們來看一個簡單的例子:git
var employee1 = new Object(); employee1.position = "Front end engineer"; employee1.tool = "I love vscode."; employee1.introduction = function () { console.log("I am a " + this.position + ", and " + this.tool); } var employee2 = new Object(); employee2.position = "UI designer"; employee2.tool = "I love photoshop."; employee2.introduction = function () { console.log("I am a " + this.position + ", and " + this.tool); } employee1.introduction();//I am a Front end engineer, and I love vscode. employee2.introduction();//I am a UI designer, and I love photoshop.
在上邊這個例子中,咱們定義了兩個employee,一個是Front End Engineer,另外一個是UI designer,他們都有position屬性和tool屬性,也都有introduction方法。若是咱們須要建立不少個相似employee的對象呢,那咱們就須要重複不少相似的代碼。接下來,咱們作一些簡單的修改:github
function Employee(type) { var employee; if (type == "programmer") { employee = new Programmer(); } else if (type == "designer") { employee = new Designer(); } employee.introduction = function () { console.log("I am a " + this.position + ", and " + this.tool); } return employee; } function Programmer() { this.position = "Front end engineer"; this.tool = "I love vscode."; } function Designer() { this.position = "UI designer"; this.tool = "I love photoshop."; } var employee1 = Employee("programmer"); employee1.introduction();//I am a Front end engineer, and I love vscode. var employee2 = Employee("designer"); employee2.introduction();//I am a UI designer, and I love photoshop.
在上邊這段代碼中,咱們將employee的初始化分別放到了Programmer()和Designer()中實現。這其實就是一個簡單工廠模式的例子,Employee是一個工廠,能夠根據傳入的type的不一樣,建立不一樣的employee,每一個employee有本身的職位和使用的工具,每一個employee均可以介紹本身的這些信息。框架
jQuery中的$()其實就是一個工廠函數,它根據傳入參數的不一樣建立元素或者去尋找上下文中的元素,建立成相應的jQuery對象。
如下實例來自於https://github.com/jquery/jqu...函數
init = jQuery.fn.init = function( selector, context, root ) { var match, elem; // HANDLE: $(""), $(null), $(undefined), $(false) if ( !selector ) { return this; } // Method init() accepts an alternate rootjQuery // so migrate can support jQuery.sub (gh-2101) root = root || rootjQuery; // Handle HTML strings if ( typeof selector === "string" ) { //... // HANDLE: $(DOMElement) } else if ( selector.nodeType ) { //.... // HANDLE: $(function) // Shortcut for document ready } else if ( jQuery.isFunction( selector ) ) { //.... } return jQuery.makeArray( selector, this ); };
同時,像Angular二、Node、Vue、React等等,不少開源框架中其實都用到了工廠模式,學會工廠模式,有助於你更好的理解和使用這些框架。工具
當須要根據不一樣參數產生不一樣實例,這些實例都有相同的行爲,這時候咱們可使用工廠模式,簡化實現的過程,同時也能夠減小每種對象所需的代碼量。工廠模式有利於消除對象間的耦合,提供更大的靈活性。this
注:若是不須要另一個類,或者不須要在運行期間判斷實例化的對象屬於哪一個類,那就不須要使用工廠模式,大多數狀況下使用new關鍵字和構造函數公開實例化對象,提升代碼可讀性。切勿濫用。code