Java簡單工廠模式詳細解釋
簡單工廠模式概述
1.定義:定義一個工廠類,他可以根據參數的不同返回不同類的實例,被創建的實例通常都具有共同的父類
2.在簡單工廠模式中用於被創建實例的方法通常為靜態(static)方法,因此簡單工廠模式又被成為靜態工廠方法(Static Factory Method)
3.需要什麼,隻需要傳入一個正確的參數,就可以獲取所需要的對象,而無需知道其實現過程
4.例如,我開一傢披薩店,當客戶需要某種披薩並且我這傢店裡也能做的時候,我就會為其提供所需要的披薩(當然是要錢的哈哈),如果其所需的我這沒有,則是另外的情況,後面會談。這時候,我這傢 披薩店就可以看做工廠(Factory),而生產出來的披薩被成為產品(Product),披薩的名稱則被稱為參數,工廠可以根據參數的不同返回不同的產品,這就是簡單工廠模式
簡單工廠模式的結構與實現
結構:
1.Factory
(工廠):核心部分,負責實現創建所有產品的內部邏輯,工廠類可以被外界直接調用,創建所需對象
2.Product
(抽象類產品):工廠類所創建的所有對象的父類,封裝瞭產品對象的公共方法,所有的具體產品為其子類對象
3.ConcreteProduct
(具體產品):簡單工廠模式的創建目標,所有被創建的對象都是某個具體類的實例。它要實現抽象產品中聲明的抽象方法(有關抽象類)
實現
abstract class Product { public void MethName() { //公共方法的實現 } public abstract void MethodDiff(); //聲明抽象業務方法 } class ConcreteProductA : Product { public override void MethodDiff() { //業務方法的實現 } } class Factory { public static Product GetProduct(string arg) { Product product = null; if(arg.Equals("A") { product = new ConcreteProductA(); //init } else if(arg.Equals("B")) { product = new ConcreteProductB(); //init } else { ....//其他情況 } return product; } } class Program { static void Main(string[] args) { Product product; product = Factory.GetProduct("A");//工廠類創建對象 Product.MethName(); product.MethodDiff(); } }
簡單工廠模式的簡化
1.為瞭簡化簡單工廠模式,將抽象產品類和工廠類合並,將靜態工廠方法移到抽象產品類中
客戶端可以調用產品父類的靜態工廠方法,根據不同的參數創建不同類型的產品子類對象。
簡單工廠模式的優缺點和適用環境
簡單工廠模式的優點
(1)工廠類包含必要的邏輯判斷,可以決定在什麼時候創建哪一個產品的實例。客戶端可以免除直接創建產品對象的職責
(2)客戶端無需知道所創建具體產品的類名,隻需知道參數即可
(3)也可以引入配置文件,在不修改客戶端代碼的情況下更換和添加新的具體產品類。(這也是我在開始的披薩店裡遇到沒有的披薩的解決情況)
簡單工廠模式的缺點
(1)工廠類集中瞭所有產品的創建邏輯,職責過重,一旦異常,整個系統將受影響
(2)使用簡單工廠模式會增加系統中類的個數(引入新的工廠類),增加系統的復雜度和理解難度
(3)系統擴展困難,一旦增加新產品不得不修改工廠邏輯,在產品類型較多時,可能造成邏輯過於復雜
(4)簡單工廠模式使用瞭static工廠方法,造成工廠角色無法形成基於繼承的等級結構。
簡單工廠模式的適用環境
(1)工廠類負責創建對的對象比較少,因為不會造成工廠方法中的業務邏輯過於復雜
(2)客戶端隻知道傳入工廠類的參數,對如何創建對象不關心
簡單案例
題目:
使用簡單工廠模式設計一個可以創建不同幾何圖形(Shape),如Circle,Rectangle,Triangle等繪圖工具類,每個幾何圖形均具有繪制Draw()和擦除Erase()兩個方法要求在繪制不支持的幾何圖形時,拋出一個UnsuppShapeException異常,繪制類圖並使用C#語言實現。
UML:
using System; using System.Collections.Generic; using System.Linq; using System.Text; /*使用簡單工廠模式設計一個可以創建不同幾何圖形(Shape),如Circle,Rectangle,Triangle等繪圖工具類,每個幾何圖形均具有繪制Draw()和擦除Erase()兩個方法 * 要求在繪制不支持的幾何圖形時,拋出一個UnsuppShapeException異常,繪制類圖並使用C#語言實現。 */ namespace SimpleShapeFactory { public interface InShape//圖形接口 抽象產品類 { void Draw(); void Erase(); } public class Circle : InShape//圓形類,具體產品類 { private static int count; //生成圖形計數 string radious; public Circle()//構造 { Console.WriteLine("Create Circle"); Console.WriteLine("Input the radious of Circle:"); radious = Console.ReadLine(); } public void Draw()//實現接口方法 { int Radious = int.Parse(radious); Console.WriteLine("Display circle " + (++count) +" information:"); Console.WriteLine("Circle "+ count+ " circumference:" + 2 * Radious * 3.14159); Console.WriteLine("Circle "+ count+" area:" + 3.14159 * Radious * Radious); } public void Erase()//實現接口方法 { while (true) { Console.WriteLine("Erase current shape(y/n)?"); string choose; choose = Console.ReadLine(); if (choose.Equals("y") || choose.Equals("Y")) { Console.WriteLine("Erase Circle "+count +" successfully!"); count--; break; } else if (choose.Equals("n") || choose.Equals("N")) { Console.WriteLine("Circle "+ count+" successfully saved!"); break; } else { Console.WriteLine("Input error, re-enter!"); } } } } class Rectangle : InShape//矩形類,具體產品類 { private static int count = 0;//生成圖形計數 string length; string wideth; public Rectangle()//構造 { Console.WriteLine("Create Rectangle"); Console.WriteLine("Input the length and wideth of Rectangle:"); length = Console.ReadLine(); wideth = Console.ReadLine(); } public void Draw()//實現接口方法 { int Length = int.Parse(length); int Wideth = int.Parse(wideth); Console.WriteLine("Display rectangle " + (++count) + " information:"); Console.WriteLine("Rectangle "+ count + "circumference:" + 2 * Length * Wideth); Console.WriteLine("Rectangle "+ count + "area:" + Length * Wideth); } public void Erase()//實現接口方法 { while (true) { Console.WriteLine("Erase current shape(y/n)?"); string choose; choose = Console.ReadLine(); if (choose.Equals("y") || choose.Equals("Y")) { Console.WriteLine("Erase rectangle "+count+ "successfully!"); --count; break; } else if (choose.Equals("n") || choose.Equals("N")) { Console.WriteLine("Rectangle "+ count+" successfully saved!"); break; } else { Console.WriteLine("Input error, re-enter!"); } } } } class Triangle : InShape//三角形類,具體產品類 { private static int count = 0;//生成圖形計數 string lengtha; string lengthb; string lengthc; public Triangle()//構造 { Console.WriteLine("Create Triangle"); Console.WriteLine("Input the lengtha ,lengthb and lengthc of Triangle:"); lengtha = Console.ReadLine(); lengthb = Console.ReadLine(); lengthc = Console.ReadLine(); } public void Draw()//實現接口方法 { int Lengtha = int.Parse(lengtha); int Lengthb = int.Parse(lengthb); int Lengthc = int.Parse(lengthc); if ((Lengtha + Lengthb > Lengthc) && (Lengtha + Lengthc > Lengthb) && (Lengthb + Lengthc > Lengtha)) { double S = (Lengtha + Lengthb + Lengthc) * 0.5; double area = Math.Sqrt(S * (S - Lengtha) * (S - Lengthb) * (S - Lengthc)); Console.WriteLine("Display triangle "+ (++count)+" information:"); Console.WriteLine("Triangle " + count +" circumference:" + (Lengtha + Lengthb + Lengthc)); Console.WriteLine("Triangle "+ count +" area:" + area); Erase(); } else { Console.WriteLine("Create triangle failed!"); } } public void Erase()//實現接口方法 { while (true) { Console.WriteLine("Erase shape(y/n)?"); string choose; choose = Console.ReadLine(); if (choose.Equals("y") || choose.Equals("Y")) { Console.WriteLine("Erase tirangle " +count +" successfully!"); --count; break; } else if (choose.Equals("n") || choose.Equals("N")) { Console.WriteLine("Triangle "+ count +" successfully saved!"); break; } else { Console.WriteLine("Input error, re-enter!"); } } } } class ShapeFactory//圖形工廠類,充當工廠類 { public static InShape Getshape(string type)//靜態工廠方法 { InShape shape; shape = null; if (type.Equals("Circle")) { shape = new Circle(); Console.WriteLine("Init set Circle"); shape.Draw(); shape.Erase(); } else if(type.Equals("Rectangle")) { shape = new Rectangle(); Console.WriteLine("Init set Rectangle"); shape.Draw(); shape.Erase(); } else if (type.Equals("Triangle")) { shape = new Triangle(); Console.WriteLine("Init set Triangle"); shape.Draw(); } else//異常 這裡我應該聲明調用異常處理類的,那樣會更好些 { Console.WriteLine("UnsupportShapeException!"); Console.WriteLine("Emotional reminders :Pay 1 million$ to Alipay:132****6151 can create every shape you want!!! "); } return shape; } } class Program//客戶端測試類 { static void Main(string[] args) { while (true) { InShape shape; Console.WriteLine("Please input the shape you want to create"); string str = Console.ReadLine(); shape = ShapeFactory.Getshape(str);//通過靜態工廠方法創建產品 Console.ReadLine(); } } } }
運行結果:
總結
本篇文章就到這裡瞭,希望能夠給你帶來幫助,也希望您能夠多多關註WalkonNet的更多內容!