天天看點

《JavaScript設計模式》——9.10 Factory(工廠)模式

本節書摘來自異步社群《javascript設計模式》一書中的第9章,第9.10節, 作者: 【美】addy osmani 譯者: 徐濤 更多章節内容可以通路雲栖社群“異步社群”公衆号檢視。

factory模式是另一種建立型模式,涉及建立對象的概念。其分類不同于其他模式的地方在于它不顯式地要求使用一個構造函數。而factory可以提供一個通用的接口來建立對象,我們可以指定我們所希望建立的工廠對象的類型(見圖9-9)。

《JavaScript設計模式》——9.10 Factory(工廠)模式

假設有一個ui工廠,我們要建立一個ui元件的類型。不需要直接使用new運算符或者通過另一個建立型構造函數建立這個元件,而是要求factory對象建立一個新的元件。我們通知factory需要什麼類型的對象(如“按鈕”、“面闆”),它會進行執行個體化,然後将它傳回給我們使用。

如果對象建立過程相對比較複雜,這種方法特别有用,例如,如果它強烈依賴于動态因素或應用程式配置的話。

可以在extjs等ui庫中找到此模式的示例,其中建立對象或元件的方法也有可能被歸入子類了。

下面這個示例建構在之前的代碼片段之上,使用constructor模式邏輯來定義汽車。它展示了如何使用factory模式來實作vehicle工廠:

// types.js –本例構造函數的存放檔案

// 定義car構造函數

// 定義truck構造函數

// factoryexample.js

// 定義vehicle工廠的大體代碼

// 定義該工廠factory的原型和試用工具,預設的vehicleclass是car

// 建立新vehicle執行個體的工廠方法

// 建立生成汽車的工廠執行個體

// 測試汽車是由vehicleclass的原型prototype裡的car建立的

// 輸出: true

// 輸出: car對象,color: "yellow", doors: 6,state:"brand new"

在方法 1 中,我們修改了vehiclefactory執行個體來使用truck類:

// 測試卡車是由vehicleclass的原型prototype裡的truck建立的

// 輸出: truck對象,color :"red", state:"like new" ,wheelsize:"small"

在方法2中,我們把vehiclefactory歸入子類來建立一個建構truck的工廠類:

// 确認mybigtruck是由原型truck建立的

// 輸出:truck對象,color: pink", wheelsize: "so big", state: "omg. so bad"

9.10.1 何時使用factory模式

factory模式應用于如下場景時是特别有用的:

當對象或元件設定涉及高複雜性時

當需要根據所在的不同環境輕松生成對象的不同執行個體時

當處理很多共享相同屬性的小型對象或元件時

在編寫隻需要滿足一個api契約(亦稱鴨子類型)的其他對象的執行個體對象時。對于解耦是很有用的。

9.10.2 何時不應使用factory模式

如果應用錯誤,這種模式會為應用程式帶來大量不必要的複雜性。除非為建立對象提供一個接口是我們正在編寫的庫或架構的設計目标,否則我建議堅持使用顯式構造函數,以避免不必要的開銷。

由于對象建立的過程實際上是藏身接口之後抽象出來的,單元測試也可能帶來問題,這取決于對象建立的過程有多複雜。

9.10.3 abstract factory(抽象工廠)

了解抽象工廠模式也是有用的,它用于封裝一組具有共同目标的單個工廠。它能夠将一組對象的實作細節從一般用法中分離出來。

應當使用抽象工廠模式的情況是:一個系統必須獨立于它所建立的對象的生成方式,或它需要與多種對象類型一起工作。

既簡單又容易了解的示例是車輛工廠,它定義了擷取或注冊車輛類型的方法。抽象工廠可以命名為abstractvehiclefactory。抽象工廠将允許對像car或truck這樣的車輛類型進行定義,具體工廠隻需要實作履行車輛契約的類(如vehicle.prototype.drive和vehicle.prototype.breakdown)。

繼續閱讀