前言
繼裝飾者模式後接下來講工廠模式,首先先來談簡單工廠模式,工廠模式算一個很常使用到的設計模式,而簡單工廠模式算是最基本的工廠模式,在 Head First Design Patterns 中也提到更多的情況下可以當作是一種編成習慣,接下來讓我用飲料店的情境來加以說明。
實作簡單工廠模式
假設我是一間只賣綠茶的飲料店,客人買了一杯綠茶時我們會這樣做,如下
但是,如果只賣綠茶已經不能應付客人想多選擇的需求,我們就必須增加更多個飲料品項,現在我們增加了紅茶供客人選擇,如下
這樣客人就多了紅茶可以選擇,可是這裡我突然想到依照前幾篇的設計模式經驗,當飲料品項繼續增加的時候,我的 BeverageStores 類別就必須加入對應的飲品方法,但是這些飲品方法內做的事情其實是一樣的,我們可以發現 AddMaterial() 、Brew() 、 PouredCup() 三個方法都是固定必須處理的事情,這時候我們就可以透過使用介面將這些動作進行封裝,所以我們將這三個方法加入介面中,如下
接著必須將飲料類別實作介面方法後再調整產生飲料的方法,如下
現在透過回傳 IBeverageProvide 介面的方式,我可以不用再增加多餘的飲品方法了,但這時又產生了新的問題,我想到在 OO 的守則下因遵循「類別應該開放便於擴充、應該關閉禁止修改」,但由於我們是使用 IF ELSE 與 new 關鍵字來實體化對象類別,所以當增加新飲品時修改應是不可避免的,但是我們已經知道了哪些地方是必須要修改的,所以我應該將這些地方提出來進行封裝,以減少 BeverageStores 類別對於飲料類別的相依性。
我再次調整 BeverageOrders 類別,將產生實體化的部分提取出到一個新的 SimpleBeverageFactory 類別中,如下
由以上程式碼可以看到 SimpleBeverageFactory 類別將產生飲品實體的邏輯置入 CreateBeverage 方法中,透過將產生實體的邏輯區段提出後放置到另一個類別中,我們就可以稱此類別為一個工廠類別,由這個類別的 CreateBeverage 方法來決定要產生哪一個飲品類別,日後如要增加新飲品類別就由此處修改即可。
接著我們需要調整原本的 BeverageStores 類別,讓此類別能夠透過傳入對應的工廠類別建立飲品的實體,如下
而套用工廠模式前的類別圖如下,BeverageStores 類別直接關聯了 GreenTea 類別與 BlackTea 類別
而透過介面與簡單工廠模式封裝後如下,BeverageStores 類別切開了與 GreenTea 類別及 BlackTea 類別的關聯性,讓 BeverageStores 類別改關聯於 SimpleBeverageFactory 工廠類別,SimpleBeverageFactory 工廠類別則透過 IBeverageProvide 飲品介面切開與飲品類別的關聯,降低了各類別的耦合性。
最後讓我們來製作飲料給客人吧 :P
範例程式碼
參考資料
Head First Design Patterns 深入淺出設計模式
沒有留言:
張貼留言