前一章節,我們介紹了簡單工廠模式以及工廠方法模式,但是這兩種模式都存在一定的局限性,只能生產某一類型下的某一種產品,如果需求變更,同類型下出現了不同的產品,比如芝士披薩不僅有口味上的不同,同時存在外觀上的不同。這種時候,工廠模式顯然不再滿足要求,該怎麼辦呢?於是我們想到DIP原則,它不正是為瞭解決這 ...
前一章節,我們介紹了簡單工廠模式以及工廠方法模式,但是這兩種模式都存在一定的局限性,只能生產某一類型下的某一種產品,如果需求變更,同類型下出現了不同的產品,比如芝士披薩不僅有口味上的不同,同時存在外觀上的不同。這種時候,工廠模式顯然不再滿足要求,該怎麼辦呢?於是我們想到DIP原則,它不正是為瞭解決這種情況而存在的嗎?接下來我們來介紹下抽象工廠模式:
1、抽象工廠模式定義了一個interface用於創建相關或有依賴關係的對象簇,而無需指明具體的類。
2、抽象工廠模式可以將簡單工廠模式和工廠方法模式進行整合。
3、從設計層面來說,抽象工廠模式就是對簡單工廠模式的改進(即進一步抽象化)
4、將工廠抽象成兩層,抽象工廠和具體的實現工廠。
還是拿pizza訂購舉例,我們定義一個抽象工廠AbsFactory,由子類工廠實現該抽象工廠;訂購披薩OrderPizza依賴抽象,不依賴具體的實現。
1 internal class Program 2 { 3 private static void Main(string[] args) 4 { 5 new OrderPizza(new BJFactory()); 6 } 7 } 8 9 internal class OrderPizza 10 { 11 private AbsFactory factory; 12 13 public OrderPizza(AbsFactory factory) 14 { 15 setFactory(factory); 16 Order(); 17 } 18 19 private void setFactory(AbsFactory factory) 20 { 21 this.factory = factory; 22 } 23 24 private void Order() 25 { 26 Pizza pizza = null; 27 string orderType = ""; 28 do 29 { 30 Console.Write("請輸入訂購類型:"); 31 orderType = Console.ReadLine(); 32 pizza = this.factory.createPizza(orderType); 33 if (pizza == null) 34 { 35 Console.WriteLine("訂購失敗"); 36 break; 37 } 38 //開始製作 39 pizza.prepare(); 40 pizza.bake(); 41 pizza.cut(); 42 pizza.box(); 43 } while (true); 44 } 45 } 46 47 internal interface AbsFactory 48 { 49 Pizza createPizza(string orderType); 50 } 51 52 internal class BJFactory : AbsFactory 53 { 54 public Pizza createPizza(string orderType) 55 { 56 Pizza pizza = null; 57 if (orderType == "cheese") 58 { 59 pizza = new BJCheesePizza(); 60 pizza.setName("北京芝士披薩"); 61 } 62 else if (orderType == "greek") 63 { 64 pizza = new BJGreekPizza(); 65 pizza.setName("北京希臘披薩"); 66 } 67 return pizza; 68 } 69 } 70 71 internal class LDFactory : AbsFactory 72 { 73 public Pizza createPizza(string orderType) 74 { 75 Pizza pizza = null; 76 if (orderType == "cheese") 77 { 78 pizza = new LDCheesePizza(); 79 pizza.setName("倫敦芝士披薩"); 80 } 81 else if (orderType == "greek") 82 { 83 pizza = new LDGreekPizza(); 84 pizza.setName("倫敦希臘披薩"); 85 } 86 return pizza; 87 } 88 } 89 90 internal abstract class Pizza 91 { 92 private string name; 93 94 public abstract void prepare(); 95 96 public void bake() 97 { 98 Console.WriteLine($"{this.name} 烘培"); 99 } 100 101 public void cut() 102 { 103 Console.WriteLine($"{this.name} 修剪"); 104 } 105 106 public void box() 107 { 108 Console.WriteLine($"{this.name} 打包"); 109 } 110 111 public void setName(string name) 112 { 113 this.name = name; 114 } 115 } 116 117 internal class BJCheesePizza : Pizza 118 { 119 public override void prepare() 120 { 121 Console.WriteLine("北京的芝士披薩準備中"); 122 } 123 } 124 125 internal class BJGreekPizza : Pizza 126 { 127 public override void prepare() 128 { 129 Console.WriteLine("北京的希臘披薩準備中"); 130 } 131 } 132 133 internal class LDCheesePizza : Pizza 134 { 135 public override void prepare() 136 { 137 Console.WriteLine("倫敦的芝士披薩準備中"); 138 } 139 } 140 141 internal class LDGreekPizza : Pizza 142 { 143 public override void prepare() 144 { 145 Console.WriteLine("倫敦的希臘披薩準備中"); 146 } 147 }view code
讀過一些博主的博文以及評論,有一些理解還是蠻到位的:
1、抽象工廠比工廠方法複雜的多,它們的目的不同。工廠方法意在延遲載入,而抽象方法意在高內聚低耦合。
2、工廠方法模式的具體工廠類只能創建一個具體具體產品類的實例,而抽象工廠可以創建多個。
參考:https://www.runoob.com/design-pattern/abstract-factory-pattern.html