2013年9月3日 星期二

[轉貼] [Design Pattern] 簡單工廠模式 (Simple Factory Pattern) 不怕飲料有幾種

出處:http://www.dotblogs.com.tw/joysdw12/archive/2013/06/23/design-pattern-simple-factory-pattern.aspx


前言


  繼裝飾者模式後接下來講工廠模式,首先先來談簡單工廠模式,工廠模式算一個很常使用到的設計模式,而簡單工廠模式算是最基本的工廠模式,在 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 深入淺出設計模式

沒有留言:

張貼留言