簡單工廠及工廠模式
簡單例子,Operation Class
我們先來看看一個簡單的例子,這裡有一個 Operation 的 abstract class,底下有 OperationAdd 和 OperationSub 繼承。
operation.ts
1 | export abstract class Operation { |
在 Client 端的使用上就會像是下面的程式碼,需要分別引入 OperationAdd
及 OperationSub
,有什麼 Operation 就引入什麼。
1 | import { OperationAdd, OperationSub } from './operation.ts'; |
這樣做的缺點就是當我要新增另一個 Operation 時,我需要額外引入這個新的 Operation,並且建立 instance。但如果採用「簡單工廠模式」,Client 端就不需要考慮這些!
工廠的作用,顧名思義就是生產產品,例如「加法」和「減法」Operation 是產品,那麼就可以統一由一個工廠創造不同的 Operation 這些產品。
簡單工廠模式 Simple Factory Pattern
簡單工廠模式又稱做靜態工廠(Static Factory)模式,在此模式中,除了事先定義的 OperationAdd
及 OperationSub
等所謂的「產品」外,我們要新增一個工廠 Class,用來產生這些 Operation:
simpleFactory.ts
1 | import { OperationAdd, OperationSub } from './operation.ts'; |
有了這樣的簡單工廠,我們在 Client 端就可以略過引入不同 Operation class 及新增 instance 的步驟。
1 | import { OperationSimpleFactory } from './simpleFactory.ts'; |
新增 Operation
在「簡單工廠模式」下,如果要新增一個 Operation,除了新增 Operation Class 外,還會需要修改簡單工廠中的 switch case。
在 operation.ts
中新增
1 | export class OperationMul extends Operation { |
然後在簡單工廠 simpleFactory.ts
中新增
1 | import { OperationAdd, OperationSub, OperationMul } from './operation.ts'; // Add here |
這種作法的缺點是每次新增一個 Operation,都要修改 OperationSimpleFactory Class,這顯然違反了 OCP(Open-Closed Priciple),這條原則告訴我們要新增功能時要避免修改,免得在 Operation(也就是工廠的產品)越來越多得情況下,會讓這個「簡單工廠」變得肥大而容易出錯。
因此雖然在「間單工廠模式」產品不多的情況下蠻簡單明瞭的,但會有上述的疑慮,這時就可以考慮另一種模式:工廠模式。
工廠模式 Factory Pattern
工廠模式也可以稱作工廠方法模式(Factory Method Pattern),將原本只有一個工廠改寫成多個工廠,將生產不同產品的工廠切開來,例如加法工廠就獨立成 OperationAddFactory
,但都要繼承同一個工廠的規格。
下面的 code 為 factory.ts
,這裡先簡單寫成一個檔案,實際上會將每個工廠拆成單獨的檔案
1 | import { OperationAdd, OperationSub } from './operation.ts'; |
Client 端的使用上則可以用
1 | import { OperationAddFactory, OperationSubFactory } from 'factory.ts'; |
但仔細一看,這豈不是又和沒有工廠的情況下一樣了嗎?我加法和減法運算都得分開引入,差別只在於一個建立 Operation 而另一個建立 OperationFactory 的 instance 而已。
確實如此,在簡單的情況下看起來的結果沒什麼優點,但工廠模式在增加新的 Operation 時不需修改工廠,也不用修改 Operation,是符合 OCP 的精神的。
由於我們已經定義了工廠的模板 OperationFactory
,新的工廠只要繼承這個 abstract class 即可。
小結
簡單工廠模式透過定義一個工廠,用 switch case 的方式將原本需要引入 Class 改為傳入 string 等參數即可得到 instance。
工廠模式則更定義了工廠的 interface,以避免新增產品時修改到既有檔案,符合 OCP 的精神。
但實際上這兩種設計模式都沒辦法在新增功能時,不修改呼叫的 Client 端。
參考資料
- 大話設計模式,第八章:工廠方法模式
- Wiki - 工廠方法