《C#設計模式》 三種工廠設計模式
-
【簡單工廠模式】
-
【工廠方法模式】
-
【抽象工廠模式】
第一種:簡單工廠模式
一:【簡單工廠模式】
簡單工廠模式概念(Simple Factory Pattern):定義一個工廠類,它可以根據參數的不同返回不同類的實例,被創建的實例通常都具有共同的父類。因爲在簡單工廠模式中用於創建實例的方法是靜態(static)方法,因此簡單工廠模式又被稱爲靜態工廠方法(Static Factory Method)模式,它屬於類創建型模式。
二: 案例分析
使用簡單工廠模式設計一個可以創建不同幾何形狀(如圓形、方形和三角形等)的繪圖工具,每個幾何圖形都具有繪製draw()和擦除erase()兩個方法;
首先定義一個接口類;包含兩個方法;繪製;擦除;
interface Draws
{
//繪製圖形
void draw();
//擦除圖形
void erase();
}
再在某個具體產品類繼承這個Draws接口;以下爲三種圖形實現方式;
//==============================================================
// 作者:zhoupei
// 時間:2019/2/18 14:12:11
// 文件名:Circular
// 版本:V1.0.1
// 說明:圓形具體產品類
//==============================================================
class Circular : Draws
{
public void draw()
{
Console.WriteLine("繪製圓形圖形");
}
public void erase()
{
Console.WriteLine("擦除圓形圖形");
}
}
class Rectangle : Draws
{
//繪製矩形
public void draw()
{
Console.WriteLine("繪製矩形圖形");
}
//擦除矩形
public void erase()
{
Console.WriteLine("擦除矩形圖形");
}
}
class Triangle: Draws
{
public void draw()
{
Console.WriteLine("繪製三角形圖形");
}
public void erase()
{
Console.WriteLine("擦除三角形圖形");
}
}
再寫個圖形處理工廠類,靜態工廠方法;
class FigureFactory
{
//靜態工廠方法
public static Draws Getfigure(string figtype)
{
Draws dws = null;
switch (figtype.ToLower())
{
case "rectangle":
dws = new Rectangle();
break;
case "triangle":
dws = new Rectangle();
break;
case "circular":
dws = new Rectangle();
break;
default:
dws = null;
break;
}
return dws;
}
}
客戶端調用方法,這裏根據讀取全局配置文件的方式來獲取路徑;
添加app.config文件;配置路徑;
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="figureType" value="Circular"/> //傳入圓形
</appSettings>
</configuration>
Main函數調用方法;
static void Main(string[] args)
{
Draws dw;
string figurestr = ConfigurationSettings.AppSettings["figureType"];
dw = FigureFactory.Getfigure(figurestr);
dw.draw();//繪製 - 圓形
dw.erase();//擦除 - 圓形
Console.ReadLine();
}
優缺點總結:
1. 主要優點
簡單工廠模式的主要優點如下:
(1) 工廠類包含必要的判斷邏輯,可以決定在什麼時候創建哪一個產品類的實例,客戶端可以免除直接創建產品對象的職責,而僅僅“消費”產品,簡單工廠模式實現了對象創建和使用的分離。
(2) 客戶端無須知道所創建的具體產品類的類名,只需要知道具體產品類所對應的參數即可,對於一些複雜的類名,通過簡單工廠模式可以在一定程度減少使用者的記憶量。
(3) 通過引入配置文件,可以在不修改任何客戶端代碼的情況下更換和增加新的具體產品類,在一定程度上提高了系統的靈活性。
2. 主要缺點
簡單工廠模式的主要缺點如下:
(1) 由於工廠類集中了所有產品的創建邏輯,職責過重,一旦不能正常工作,整個系統都要受到影響。
(2) 使用簡單工廠模式勢必會增加系統中類的個數(引入了新的工廠類),增加了系統的複雜度和理解難度。
(3) 系統擴展困難,一旦添加新產品就不得不修改工廠邏輯,在產品類型較多時,有可能造成工廠邏輯過於複雜,不利於系統的擴展和維護。
(4) 簡單工廠模式由於使用了靜態工廠方法,造成工廠角色無法形成基於繼承的等級結構。
第二種:工廠方法模式
工廠方法模式概念:工廠方法模式(Factory Method Pattern):定義一個用於創建對象的接口,讓子類決定將哪一個類實例化。工廠方法模式讓一個類的實例化延遲到其子類。工廠方法模式又簡稱爲工廠模式(Factory Pattern),又可稱作虛擬構造器模式(Virtual Constructor Pattern)或多態工廠模式(Polymorphic Factory Pattern)。工廠方法模式是一種類創建型模式。
案例分析:使用工廠方法模式設計一個程序來讀取各種不同類型的圖片格式,針對每一種圖片格式都設計一個圖片讀取器,如GIF圖片讀取器用於讀取GIF格式的圖片、JPG圖片讀取器用於讀取JPG格式的圖片。需充分考慮系統的靈活性和可擴展性。
首先定義圖片接口 即抽象產品類;代碼如下!
/// <summary>
/// 圖片處理接口
/// 抽象產品:它是定義產品的接口,是工廠方法模式所創建對象的超類型,也就是產品對象的公共父類。
/// </summary>
interface Imager
{
void GetImages();
}
然後定義抽象工工廠類; 代碼如下!
interface ImagerFactory
{
Imager GetImagelist(); //抽象產品工廠類
}
現在客戶需求裏要分別讀取處理JPG格式的圖片跟GIF格式的圖片;
具體產品類
//==============================================================
// 作者:zhoupei
// 時間:2019/2/18 11:45:23
// 文件名:GifImg
// 版本:V1.0.1
// 說明:Gif圖片 - 具體產品類
//==============================================================
class GifImg : Imager
{
public void GetImages()
{
Console.WriteLine("讀取GIF圖片。");
}
}
class JpgImg : Imager
{
public void GetImages()
{
Console.WriteLine("讀取Jpg圖片。");
}
}
具體產品工廠
//==============================================================
// 作者:zhoupei
// 時間:2019/2/18 11:46:05
// 文件名:GifImgFactory
// 版本:V1.0.1
// 說明:產品具體工廠
//==============================================================
class GifImgFactory : ImagerFactory //繼承自抽象產品類
{
public Imager GetImagelist()
{
Imager im = new GifImg();
return im;
}
}
class JpgImgFactory : ImagerFactory
{
public Imager GetImagelist()
{
Imager im = new JpgImg();
return im;
}
}
客戶端Main()調用: 方式跟以上一樣
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="imageFactory" value="FactoryMethod.JpgImgFactory"/>
</appSettings>
</configuration>
static void Main(string[] args)
{
ImagerFactory ifc;
Imager img;
string factStr = ConfigurationManager.AppSettings["imageFactory"];
ifc = (JpgImgFactory)Assembly.Load("FactoryMethod").CreateInstance(factStr);
img = ifc.GetImagelist();
img.GetImages();
Console.ReadLine();
}
工廠方法模式總結:
1. 主要優點
工廠方法模式的主要優點如下:
(1) 在工廠方法模式中,工廠方法用來創建客戶所需要的產品,同時還向客戶隱藏了哪種具體產品類將被實例化這一細節,用戶只需要關心所需產品對應的工廠,無須關心創建細節,甚至無須知道具體產品類的類名。
(2) 基於工廠角色和產品角色的多態性設計是工廠方法模式的關鍵。它能夠讓工廠可以自主確定創建何種產品對象,而如何創建這個對象的細節則完全封裝在具體工廠內部。工廠方法模式之所以又被稱爲多態工廠模式,就正是因爲所有的具體工廠類都具有同一抽象父類。
(3) 使用工廠方法模式的另一個優點是在系統中加入新產品時,無須修改抽象工廠和抽象產品提供的接口,無須修改客戶端,也無須修改其他的具體工廠和具體產品,而只要添加一個具體工廠和具體產品就可以了,這樣,系統的可擴展性也就變得非常好,完全符合“開閉原則”。
2. 主要缺點
工廠方法模式的主要缺點如下:
(1) 在添加新產品時,需要編寫新的具體產品類,而且還要提供與之對應的具體工廠類,系統中類的個數將成對增加,在一定程度上增加了系統的複雜度,有更多的類需要編譯和運行,會給系統帶來一些額外的開銷。
(2) 由於考慮到系統的可擴展性,需要引入抽象層,在客戶端代碼中均使用抽象層進行定義,增加了系統的抽象性和理解難度,且在實現時可能需要用到DOM、反射等技術,增加了系統的實現難度。
第三中:抽象工廠模式
抽象工廠模式概述:提供一個創建一系列相關或相互依賴對象的接口,而無須指定它們具體的類。抽象工廠模式又稱爲Kit模式,它是一種對象創建型模式。
案例分析:某個軟件公司欲推出一款新的手機遊戲軟件,該軟件能夠支持Symbian、Android和Windows Mobile等多個智能手機操作系統平臺,針對不同的手機操作系統,該遊戲軟件提供了不同的遊戲操作控制(OperationController)類和遊戲界面控制(InterfaceController)類,並提供相應的工廠類來封裝這些類的初始化過程。軟件要求具有較好的擴展性以支持新的操作系統平臺,爲了滿足上述需求,試採用抽象工廠模式對其進行設計。
具體實現:
//抽象產品類
interface Android
{
void Description();
}
interface Apple
{
void Description();
}
interface ASymbian
{
void Description();
}
抽象工廠類:
/// <summary>
/// 遊戲支持系統抽象工廠
/// </summary>
interface GameFactory
{
ASymbian CanRunonSymbian();
Android CanRunonAndroid();
Apple CanRunonApple();
}
具體產品類
//==============================================================
// 作者:zhoupei
// 時間:2019/2/18 16:08:35
// 文件名:InterfaceControllerOnAndroid
// 版本:V1.0.1
// 說明:安卓系統支持InterfaceControllerOnAndroid
//==============================================================
class InterfaceControllerOnAndroid : Android
{
public void Description()
{
Console.WriteLine("安卓系統支持InterfaceControllerOnAndroid遊戲操作控制");
}
}
class InterfaceControllerOnApple : Apple
{
public void Description()
{
Console.WriteLine("蘋果支持 InterfaceController遊戲操作控制");
}
}
class InterfaceControllerOnSymbian :ASymbian
{
public void Description()
{
Console.WriteLine("塞班系統支持InterfaceController遊戲操作控制");
}
}
//==============================================================
// 作者:zhoupei
// 時間:2019/2/18 16:07:45
// 文件名:OperationControllerOnAndroid
// 版本:V1.0.1
// 說明:支持OperationController
//==============================================================
class OperationControllerOnAndroid :Android
{
public void Description()
{
Console.WriteLine("安卓系統支持OperationControllerOnAndroid遊戲操作控制");
}
}
class OperationControllerOnApple : Apple
{
public void Description()
{
Console.WriteLine("蘋果系統支持OperationController遊戲操作控制");
}
}
class OperationControllerOnSymbian : ASymbian
{
public void Description()
{
Console.WriteLine("塞班系統支持OperationController遊戲操作控制");
}
}
具體工廠類:
//==============================================================
// 作者:zhoupei
// 時間:2019/2/18 16:10:59
// 文件名:B_InterfaceController
// 版本:V1.0.1
// 說明:
//==============================================================
class B_InterfaceController : GameFactory
{
public Android CanRunonAndroid()
{
return new InterfaceControllerOnAndroid();
}
public Apple CanRunonApple()
{
return new InterfaceControllerOnApple();
}
public ASymbian CanRunonSymbian()
{
return new InterfaceControllerOnSymbian();
}
}
class B_OperationController : GameFactory
{
public Android CanRunonAndroid()
{
return new OperationControllerOnAndroid();
}
public Apple CanRunonApple()
{
return new OperationControllerOnApple();
}
public ASymbian CanRunonSymbian()
{
return new OperationControllerOnSymbian();
}
}
抽象工廠模式總結
1. 主要優點
抽象工廠模式的主要優點如下:
(1) 抽象工廠模式隔離了具體類的生成,使得客戶並不需要知道什麼被創建。由於這種隔離,更換一個具體工廠就變得相對容易,所有的具體工廠都實現了抽象工廠中定義的那些公共接口,因此只需改變具體工廠的實例,就可以在某種程度上改變整個軟件系統的行爲。
(2) 當一個產品族中的多個對象被設計成一起工作時,它能夠保證客戶端始終只使用同一個產品族中的對象。
(3) 增加新的產品族很方便,無須修改已有系統,符合“開閉原則”。
2. 主要缺點
抽象工廠模式的主要缺點如下:
增加新的產品等級結構麻煩,需要對原有系統進行較大的修改,甚至需要修改抽象層代碼,這顯然會帶來較大的不便,違背了“開閉原則”。
三種工廠方式學習總結完畢,歡迎指正,討論指教;
學習來自我的大學老師《C#設計模式》,感謝恩師;