簡單工廠模式是一種常用的創建型設計模式,它提供了一個統一的工廠方法,根據傳入的參數來創建不同的產品物件。
具體來說,簡單工廠模式通常包含以下角色:
- 產品(Product):需要創建的具體產品。
- 工廠(Factory):負責創建產品的工廠,包含一個靜態的工廠方法,根據客戶端傳入的參數創建對應的產品。
- 客戶端(Client):使用工廠創建產品的客戶端。
- 簡單工廠模式的核心是工廠方法,它負責根據客戶端傳入的參數創建對應的產品。客戶端不需要知道具體的產品是如何創建的,只需要知道傳入什麼參數就可以得到對應的產品。
在設計軟體時,我們常常需要創建不同的物件,而這些物件通常有共同的介面或繼承關係。當我們需要創建這些物件時,可以使用簡單工廠模式。
簡單工廠模式是一種創建型模式,它提供了一個共同的介面,用於創建不同類型的物件,而不需要直接指定它們的類型。簡單工廠模式可以隱藏物件創建的細節,並提高程式碼的可讀性和可維護性。
在 Delphi 中,我們可以使用 TComponent 或介面 (Interface) 來實現簡單工廠模式。下面我們將以製作蛋餅為例來展示如何使用 TComponent 和介面實現簡單工廠模式。
使用 TComponent 實現簡單工廠模式
首先,我們需要定義一個基礎的蛋餅類別 TChineseOmelette,並繼承自 TComponent。TChineseOmelette 包含兩個虛擬方法 GetName 和 GetPrice,用於取得蛋餅的名稱和價格。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
unit ChineseOmelette; interface uses System.Classes; type TChineseOmelette = class(TComponent) public function GetName: string; virtual; abstract; function GetPrice: Double; virtual; abstract; end; implementation end. |
接下來,我們需要定義具體的蛋餅類別,包括雞肉蛋餅、牛肉蛋餅、豬肉蛋餅和起司蛋餅。這些具體的蛋餅類別都繼承自 TChineseOmelette,並實現其 GetName 和 GetPrice 方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | unit ChineseOmelettes; interface uses System.Classes; type TChineseOmelette = class(TComponent) public function GetName: string; virtual; abstract; function GetPrice: Double; virtual; abstract; end; TChickenOmelette = class(TChineseOmelette) public function GetName: string; override; function GetPrice: Double; override; end; TBeefOmelette = class(TChineseOmelette) public function GetName: string; override; function GetPrice: Double; override; end; TPorkOmelette = class(TChineseOmelette) public function GetName: string; override; function GetPrice: Double; override; end; TCheeseOmelette = class(TChineseOmelette) public function GetName: string; override; function GetPrice: Double; override; end; implementation function TChickenOmelette.GetName: string; begin Result := '雞肉蛋餅'; end; function TChickenOmelette.GetPrice: Double; begin Result := 30.0; end; function TBeefOmelette.GetName: string; begin Result := '牛肉蛋餅'; end; function TBeefOmelette.GetPrice: Double; begin Result := 35.0; end; function TPorkOmelette.GetName: string; begin Result := '豬肉蛋餅'; end; function TPorkOmelette.GetPrice: Double; begin Result := 25.0; end; function TCheeseOmelette.GetName: string; begin Result := '起司蛋餅'; end; function TCheeseOmelette.GetPrice: Double; begin Result := 40.0; end; end. |
現在我們已經定義了基礎類別 TChineseOmelette 和具體類別 TChickenChineseOmelette、TBeefChineseOmelette、TPorkChineseOmelette 和 TCheeseChineseOmelette。下一步我們需要定義一個工廠類別 TChineseOmeletteFactory,用於創建不同類型的蛋餅物件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | unit ChineseOmeletteFactory; interface uses ChineseOmelette; type TChineseOmeletteType = (cotChicken, cotBeef, cotPork, cotCheese); TChineseOmeletteFactory = class public class function CreateOmelette(OmeletteType: TChineseOmeletteType): TChineseOmelette; end; implementation uses ChineseOmeletteTypes; class function TChineseOmeletteFactory.CreateOmelette(OmeletteType: TChineseOmeletteType): TChineseOmelette; begin case OmeletteType of cotChicken: Result := TChickenOmelette.Create(nil); cotBeef: Result := TBeefOmelette.Create(nil); cotPork: Result := TPorkOmelette.Create(nil); cotCheese: Result := TCheeseOmelette.Create(nil); else Result := nil; end; end; end. |
現在我們已經定義了 TChineseOmeletteFactory,我們可以使用它來創建不同類型的蛋餅物件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | procedure TForm1.Button1Click(Sender: TObject); var ChineseOmelette: TChineseOmelette; begin // 創建雞肉蛋餅 ChineseOmelette := TChineseOmeletteFactory.CreateChineseOmelette(btChicken) as TChineseOmelette; Memo1.Lines.Add(Format('%s: %.2f', [ChineseOmelette.GetName, ChineseOmelette.GetPrice])); ChineseOmelette.Free; // 創建牛肉蛋餅 ChineseOmelette := TChineseOmeletteFactory.CreateChineseOmelette(btBeef) as TChineseOmelette; Memo1.Lines.Add(Format('%s: %.2f', [ChineseOmelette.GetName, ChineseOmelette.GetPrice])); ChineseOmelette.Free; // 創建豬肉蛋餅 ChineseOmelette := TChineseOmeletteFactory.CreateChineseOmelette(btPork) as TChineseOmelette; Memo1.Lines.Add(Format('%s: %.2f', [ChineseOmelette.GetName, ChineseOmelette.GetPrice])); ChineseOmelette.Free; // 創建起司蛋餅 ChineseOmelette := TChineseOmeletteFactory.CreateChineseOmelette(btCheese) as TChineseOmelette; Memo1.Lines.Add(Format('%s: %.2f', [ChineseOmelette.GetName, ChineseOmelette.GetPrice])); ChineseOmelette.Free; end; |
至此,我們已經完成了 Delphi 簡單工廠模式的設計與實現。現在我們可以輕鬆地創建不同類型的蛋餅物件,而不必關心其具體實現細節。
使用 Interface (介面)實現簡單工廠模式
簡單工廠模式是一個常見的設計模式,在軟體開發中使用廣泛。通過這種設計模式,我們可以確實隱藏物件的具體實現細節,提高程式碼的可維護性和擴充。
除了以上的 TComponent 實現方式,我們還可以使用介面來實現簡單工廠模式。以下是介面實現方式的範例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | unit ChineseOmelette; interface type IChineseOmelette = interface function GetName: string; function GetPrice: Double; end; TChineseOmeletteType = (cotChicken, cotBeef, cotPork, cotCheese); TChineseOmeletteFactory = class public class function CreateChineseOmelette(ChineseOmeletteType: TChineseOmeletteType): IChineseOmelette; end; implementation uses ChineseOmeletteVarieties; type TChickenChineseOmelette = class(TInterfacedObject, IChineseOmelette) public function GetName: string; function GetPrice: Double; end; TBeefChineseOmelette = class(TInterfacedObject, IChineseOmelette) public function GetName: string; function GetPrice: Double; end; TPorkChineseOmelette = class(TInterfacedObject, IChineseOmelette) public function GetName: string; function GetPrice: Double; end; TCheeseChineseOmelette = class(TInterfacedObject, IChineseOmelette) public function GetName: string; function GetPrice: Double; end; { TChickenChineseOmelette } function TChickenChineseOmelette.GetName: string; begin Result := '雞肉蛋餅'; end; function TChickenChineseOmelette.GetPrice: Double; begin Result := 30.0; end; { TBeefChineseOmelette } function TBeefChineseOmelette.GetName: string; begin Result := '牛肉蛋餅'; end; function TBeefChineseOmelette.GetPrice: Double; begin Result := 35.0; end; { TPorkChineseOmelette } function TPorkChineseOmelette.GetName: string; begin Result := '豬肉蛋餅'; end; function TPorkChineseOmelette.GetPrice: Double; begin Result := 25.0; end; { TCheeseChineseOmelette } function TCheeseChineseOmelette.GetName: string; begin Result := '起司蛋餅'; end; function TCheeseChineseOmelette.GetPrice: Double; begin Result := 40.0; end; { TChineseOmeletteFactory } class function TChineseOmeletteFactory.CreateChineseOmelette(ChineseOmeletteType: TChineseOmeletteType): IChineseOmelette; begin case ChineseOmeletteType of cotChicken: Result := TChickenChineseOmelette.Create; cotBeef: Result := TBeefChineseOmelette.Create; cotPork: Result := TPorkChineseOmelette.Create; cotCheese: Result := TCheeseChineseOmelette.Create; else raise Exception.Create('Invalid Chinese omelette type.'); end; end; end. |
使用介面實現簡單工廠模式的核心在於定義一個公用介面,所有的具體產品都實現這個介面。工廠類別則根據不同的產品類型創建對應的具體產品,並返回公用介面類型的實例。
在使用簡單工廠模式時,我們需要注意以下幾點:
- 工廠類別需要負責創建產品實例,並返回公用介面類型的實例。
- 具體產品需要實現公用介面,以便工廠類別能夠創建對應的產品實例。
- 工廠類別需要知道所有支援的產品類型,並根據類型創建對應的產品實例。
- 簡單工廠模式在增加新的產品時,需要修改工廠類別的代碼。因此,它的擴充性較低,但對於簡單的應用場景來說,它仍是一個簡單而有效的設計模式。
總結
簡單工廠模式是一個常用的設計模式,它可以將物件的創建與使用分離開來,提高程式碼的可維護性和擴充性。在 Delphi 中,我們可以使用 TComponent 或介面來實現簡單工廠模式。透過這個模式,我們可以輕鬆地創建不同類型的物件,而不必關心其具體實現細節。
沒有留言:
張貼留言