簡單工廠模式概述 簡單工廠模式的結構與實現 結構: 實現 1 abstract class Product 2 { 3 public void MethName() 4 { 5 //公共方法的實現 6 } 7 public abstract void MethodDiff(); 8 //聲明抽象業務 ...
- 簡單工廠模式概述
- 定義一個工廠類,他可以根據參數的不同返回不同類的實例,被創建的實例通常都具有共同的父親
- 在簡單工廠模式中用於被創建實例的方法通常為靜態(static)方法,因此簡單工廠模式又被成為靜態工廠方法(Static Factory Method)
- 需要什麼,只需要傳入一個正確的參數,就可以獲取所需要的對象,而無需知道其實現過程
- 例如,我開一家披薩店,當客戶需要某種披薩並且我這家店裡也能做的時候,我就會為其提供所需要的披薩(當然是要錢的哈哈),如果其所需的我這沒有,則是另外的情況,後面會談。這時候,我這家 披薩店就可以看做工廠(Factory),而生產出來的披薩被成為產品(Product),披薩的名稱則被稱為參數,工廠可以根據參數的不同返回不同的產品,這就是簡單工廠模式
- 簡單工廠模式的結構與實現
- 結構:
- Factory(工廠):核心部分,負責實現創建所有產品的內部邏輯,工廠類可以被外界直接調用,創建所需對象
- Product(抽象類產品):工廠類所創建的所有對象的父類,封裝了產品對象的公共方法,所有的具體產品為其子類對象
- ConcreteProduct(具體產品):簡單工廠模式的創建目標,所有被創建的對象都是某個具體類的實例。它要實現抽象產品中聲明的抽象方法(有關抽象類)
- 實現
1 abstract class Product 2 { 3 public void MethName() 4 { 5 //公共方法的實現 6 } 7 public abstract void MethodDiff(); 8 //聲明抽象業務方法 9 } 10 class ConcreteProductA : Product 11 { 12 public override void MethodDiff() 13 { 14 //業務方法的實現 15 } 16 } 17 18 class Factory 19 { 20 public static Product GetProduct(string arg) 21 { 22 Product product = null; 23 if(arg.Equals("A") 24 { 25 product = new ConcreteProductA(); 26 //init 27 } 28 else if(arg.Equals("B")) 29 { 30 product = new ConcreteProductB(); 31 //init 32 } 33 else 34 { 35 ....//其他情況 36 } 37 return product; 38 } 39 } 40 41 class Program 42 { 43 static void Main(string[] args) 44 { 45 Product product; 46 product = Factory.GetProduct("A");//工廠類創建對象 47 Product.MethName(); 48 product.MethodDiff(); 49 } 50 }
- 簡單工廠模式的簡化
- 為了簡化簡單工廠模式,將抽象產品類和工廠類合併,將靜態工廠方法移到抽象產品類中
- 客戶端可以調用產品父類的靜態工廠方法,根據不同的參數創建不同類型的產品子類對象。
- 簡單工廠模式的優缺點和適用環境
- 簡單工廠模式的優點
(1)工廠類包含必要的邏輯判斷,可以決定在什麼時候創建哪一個產品的實例。客戶端可以免除直接創建產品對象的職責
(2)客戶端無需知道所創建具體產品的類名,只需知道參數即可
(3)也可以引入配置文件,在不修改客戶端代碼的情況下更換和添加新的具體產品類。(這也是我在開始的披薩店裡遇到沒有的披薩的解決情況)
- 簡單工廠模式的缺點
(1)工廠類集中了所有產品的創建邏輯,職責過重,一旦異常,整個系統將受影響
(2)使用簡單工廠模式會增加系統中類的個數(引入新的工廠類),增加系統的複雜度和理解難度
(3)系統擴展困難,一旦增加新產品不得不修改工廠邏輯,在產品類型較多時,可能造成邏輯過於複雜
(4)簡單工廠模式使用了static工廠方法,造成工廠角色無法形成基於繼承的等級結構。
- 簡單工廠模式的適用環境
(1)工廠類負責創建對的對象比較少,因為不會造成工廠方法中的業務邏輯過於複雜
(2)客戶端只知道傳入工廠類的參數,對如何創建對象不關心
- 簡單案例
- 題目:
使用簡單工廠模式設計一個可以創建不同幾何圖形(Shape),如Circle,Rectangle,Triangle等繪圖工具類,每個幾何圖形均具有繪製Draw()和擦除Erase()兩個方法
要求在繪製不支持的幾何圖形時,拋出一個UnsuppShapeException異常,繪製類圖並使用C#語言實現。 - UML:
-
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 /*使用簡單工廠模式設計一個可以創建不同幾何圖形(Shape),如Circle,Rectangle,Triangle等繪圖工具類,每個幾何圖形均具有繪製Draw()和擦除Erase()兩個方法 6 * 要求在繪製不支持的幾何圖形時,拋出一個UnsuppShapeException異常,繪製類圖並使用C#語言實現。 7 */ 8 9 namespace SimpleShapeFactory 10 { 11 public interface InShape//圖形介面 抽象產品類 12 { 13 void Draw(); 14 void Erase(); 15 } 16 17 public class Circle : InShape//圓形類,具體產品類 18 { 19 private static int count; //生成圖形計數 20 string radious; 21 public Circle()//構造 22 { 23 Console.WriteLine("Create Circle"); 24 Console.WriteLine("Input the radious of Circle:"); 25 radious = Console.ReadLine(); 26 } 27 public void Draw()//實現介面方法 28 { 29 int Radious = int.Parse(radious); 30 Console.WriteLine("Display circle " + (++count) +" information:"); 31 Console.WriteLine("Circle "+ count+ " circumference:" + 2 * Radious * 3.14159); 32 Console.WriteLine("Circle "+ count+" area:" + 3.14159 * Radious * Radious); 33 } 34 public void Erase()//實現介面方法 35 { 36 while (true) 37 { 38 Console.WriteLine("Erase current shape(y/n)?"); 39 string choose; 40 choose = Console.ReadLine(); 41 if (choose.Equals("y") || choose.Equals("Y")) 42 { 43 Console.WriteLine("Erase Circle "+count +" successfully!"); 44 count--; 45 break; 46 } 47 else if (choose.Equals("n") || choose.Equals("N")) 48 { 49 Console.WriteLine("Circle "+ count+" successfully saved!"); 50 break; 51 } 52 else 53 { 54 Console.WriteLine("Input error, re-enter!"); 55 } 56 } 57 } 58 } 59 60 class Rectangle : InShape//矩形類,具體產品類 61 { 62 private static int count = 0;//生成圖形計數 63 string length; 64 string wideth; 65 public Rectangle()//構造 66 { 67 Console.WriteLine("Create Rectangle"); 68 Console.WriteLine("Input the length and wideth of Rectangle:"); 69 length = Console.ReadLine(); 70 wideth = Console.ReadLine(); 71 } 72 public void Draw()//實現介面方法 73 { 74 int Length = int.Parse(length); 75 int Wideth = int.Parse(wideth); 76 Console.WriteLine("Display rectangle " + (++count) + " information:"); 77 Console.WriteLine("Rectangle "+ count + "circumference:" + 2 * Length * Wideth); 78 Console.WriteLine("Rectangle "+ count + "area:" + Length * Wideth); 79 80 } 81 public void Erase()//實現介面方法 82 { 83 while (true) 84 { 85 Console.WriteLine("Erase current shape(y/n)?"); 86 string choose; 87 choose = Console.ReadLine(); 88 if (choose.Equals("y") || choose.Equals("Y")) 89 { 90 Console.WriteLine("Erase rectangle "+count+ "successfully!"); 91 --count; 92 break; 93 } 94 else if (choose.Equals("n") || choose.Equals("N")) 95 { 96 Console.WriteLine("Rectangle "+ count+" successfully saved!"); 97 break; 98 } 99 else 100 { 101 Console.WriteLine("Input error, re-enter!"); 102 } 103 } 104 } 105 } 106 107 class Triangle : InShape//三角形類,具體產品類 108 { 109 private static int count = 0;//生成圖形計數 110 string lengtha; 111 string lengthb; 112 string lengthc; 113 public Triangle()//構造 114 { 115 Console.WriteLine("Create Triangle"); 116 Console.WriteLine("Input the lengtha ,lengthb and lengthc of Triangle:"); 117 lengtha = Console.ReadLine(); 118 lengthb = Console.ReadLine(); 119 lengthc = Console.ReadLine(); 120 121 } 122 public void Draw()//實現介面方法 123 { 124 int Lengtha = int.Parse(lengtha); 125 int Lengthb = int.Parse(lengthb); 126 int Lengthc = int.Parse(lengthc); 127 if ((Lengtha + Lengthb > Lengthc) && (Lengtha + Lengthc > Lengthb) && (Lengthb + Lengthc > Lengtha)) 128 { 129 double S = (Lengtha + Lengthb + Lengthc) * 0.5; 130 double area = Math.Sqrt(S * (S - Lengtha) * (S - Lengthb) * (S - Lengthc)); 131 Console.WriteLine("Display triangle "+ (++count)+" information:"); 132 Console.WriteLine("Triangle " + count +" circumference:" + (Lengtha + Lengthb + Lengthc)); 133 Console.WriteLine("Triangle "+ count +" area:" + area); 134 Erase(); 135 } 136 else 137 { 138 Console.WriteLine("Create triangle failed!"); 139 } 140 } 141 public void Erase()//實現介面方法 142 { 143 while (true) 144 { 145 Console.WriteLine("Erase shape(y/n)?"); 146 string choose; 147 choose = Console.ReadLine(); 148 if (choose.Equals("y") || choose.Equals("Y")) 149 { 150 Console.WriteLine("Erase tirangle " +count +" successfully!"); 151 --count; 152 break; 153 } 154 else if (choose.Equals("n") || choose.Equals("N")) 155 { 156 Console.WriteLine("Triangle "+ count +" successfully saved!"); 157 break; 158 } 159 else 160 { 161 Console.WriteLine("Input error, re-enter!"); 162 } 163 } 164 } 165 } 166 167 class ShapeFactory//圖形工廠類,充當工廠類 168 { 169 public static InShape Getshape(string type)//靜態工廠方法 170 { 171 InShape shape; 172 shape = null; 173 if (type.Equals("Circle")) 174 { 175 shape = new Circle(); 176 Console.WriteLine("Init set Circle"); 177 shape.Draw(); 178 shape.Erase(); 179 } 180 else if(type.Equals("Rectangle")) 181 { 182 shape = new Rectangle(); 183 Console.WriteLine("Init set Rectangle"); 184 shape.Draw(); 185 shape.Erase(); 186 } 187 else if (type.Equals("Triangle")) 188 { 189 shape = new Triangle(); 190 Console.WriteLine("Init set Triangle"); 191 shape.Draw(); 192 193 } 194 else//異常 這裡我應該聲明調用異常處理類的,那樣會更好些 195 { 196 Console.WriteLine("UnsupportShapeException!"); 197 Console.WriteLine("Emotional reminders :Pay 1 million$ to Alipay:132****6151 can create every shape you want!!! "); 198 } 199 return shape; 200 } 201 } 202 203 class Program//客戶端測試類 204 { 205 static void Main(string[] args) 206 { 207 while (true) 208 { 209 InShape shape; 210 Console.WriteLine("Please input the shape you want to create"); 211 string str = Console.ReadLine(); 212 shape = ShapeFactory.Getshape(str);//通過靜態工廠方法創建產品 213 Console.ReadLine(); 214 } 215 } 216 } 217 }
- 運行結果:
- 自我感覺寫的一般般,如有不對的地方,歡迎指正。