介紹
簡單工廠模式不能說是一個設計模式,說它是一種編程習慣可能更恰當些。由於它至少不是Gof23種設計模式之一。但它在實際的編程中常常被用到,並且思想也很是簡單,能夠說是工廠方法模式的一個引導,因此我想有必要把它做爲第一個講一下。編程
模式動機
考慮一個簡單的軟件應用場景,一個軟件系統能夠提供多個外觀不一樣的按鈕(如圓形按鈕、矩形按鈕、菱形按鈕等),這些按鈕都源自同一個基類,不過在繼承基類後不一樣的子類修改了部分屬性從而使得它們能夠呈現不一樣的外觀,若是咱們但願在使用這些按鈕時,不須要知道這些具體按鈕類的名字,只須要知道表示該按鈕類的一個參數,並提供一個調用方便的方法,把該參數傳入方法便可返回一個相應的按鈕對象,此時,就可使用簡單工廠模式。設計模式
模式定義
簡單工廠模式(Simple Factory Pattern):又稱爲靜態工廠方法(Static Factory Method)模式,它屬於類建立型模式。在簡單工廠模式中,能夠根據參數的不一樣返回不一樣類的實例。簡單工廠模式專門定義一個類來負責建立其餘類的實例,被建立的實例一般都具備共同的父類。spa
模式結構
簡單工廠模式包含以下角色:
Factory:工廠角色
Product:抽象產品角色
ConcreteProduct:具體產品角色設計
工廠角色(Creator)code |
是簡單工廠模式的核心,它負責實現建立全部具體產品類的實例。工廠類能夠被外界直接調用,建立所需的產品對象。對象 |
抽象產品角色(Product)blog
|
是全部具體產品角色的父類,它負責描述全部實例所共有的公共接口。繼承
|
具體產品角色(Concrete Product)接口
|
繼承自抽象產品角色,通常爲多個,是簡單工廠模式的建立目標。工廠類返回的都是該角色的某一具體產品。ci
|
UML圖
現實生活中例子
每次參加不一樣的聚會或者與不一樣的人見面,可能穿的衣服是不同的,好比,你今天上午要與你的一個新客戶見面,你可能會對你的老婆說:老婆,給拿件商務裝(參數),我要去見個人一個客戶,你老婆(工廠類)接到你的請求(商務裝參數)後,從衣櫃中取出一件商務裝(具體產品),交給你。整個過程就完成了。
你可能根據不一樣的條件,要的衣服是不同的,但要的衣服都是已經在你的衣櫃中存在的。而且,每件上衣它們都屬於同一種抽象,即它們能夠從一個抽象類或接口中繼承,這此衣服各自都有必定特徵,這些都是條件。而後你要的時候,就能夠向你老婆說一種特徵,她就會根據這個特徵爲你服務了。這就是典型的簡單工廠模式的應用。
模式實例與解析
Product:抽象產品角色 ICoat.cs
namespace SimpleFactory { /// <summary> /// 抽象產品類:上衣 /// </summary> public interface ICoat { void GetYourCoat(); } }
ConcreteProduct:具體產品角色
BusinessCoat.cs
using System; namespace SimpleFactory { /// <summary> /// 具體產品類:商務上衣 /// </summary> public class BusinessCoat : ICoat { public void GetYourCoat() { Console.WriteLine("商務上衣"); } } }
FashionCoat.cs
using System; namespace SimpleFactory { /// <summary> /// 具體產品類:時尚上衣 /// </summary> public class FashionCoat : ICoat { public void GetYourCoat() { Console.WriteLine("時尚上衣"); } } }
Factory:工廠角色 Factory.cs
using System; namespace SimpleFactory { /// <summary> /// 簡單工廠模式中的核心部分:工廠類 /// </summary> public class Factory { public ICoat CreateCoat(string styleName) { switch (styleName.Trim().ToLower()) { case "business": //商務上衣 return new BusinessCoat(); case "fashion"://時尚上衣 return new FashionCoat(); default: throw new Exception("尚未你要的那種衣服"); } } } }
Program.cs
using System; namespace SimpleFactory { /// <summary> /// 客戶類 /// </summary> class Client { static void Main(string[] args) { ICoat food; try { Factory factory = new Factory(); Console.Write("請選擇:時尚上衣 fashion,商務上衣 business\t"); string choice = Console.ReadLine(); switch (choice) { case "fashion"://時尚上衣 Console.Write("我要的是時尚上衣\t"); food = factory.CreateCoat("fashion"); food.GetYourCoat(); break; case "business": //商務上衣 Console.Write("我要的是商務上衣\t"); food = factory.CreateCoat("business"); food.GetYourCoat(); break; default: Console.Write("尚未你要的那種衣服\t"); break; } Console.ReadLine(); } catch (Exception ex) { Console.WriteLine(ex.Message); } } } }
體系結構
模式分析
將對象的建立和對象自己業務處理分離能夠下降系統的耦合度,使得二者修改起來都相對容易。
在調用工廠類的工廠方法時,因爲工廠方法是靜態方法,使用起來很方便,可經過類名直接調用,並且只須要傳入一個簡單的參數便可,在實際開發中,還能夠在調用時將所傳入的參數保存在XML等格式的配置文件中,修改參數時無須修改任何源代碼。
簡單工廠模式最大的問題在於工廠類的職責相對太重,增長新的產品須要修改工廠類的判斷邏輯,這一點與開閉原則是相違背的。
簡單工廠模式的要點在於:當你須要什麼,只須要傳入一個正確的參數,就能夠獲取你所須要的對象,而無須知道其建立細節。
模式優缺點
工廠類含有必要的判斷邏輯,能夠決定在何時建立哪個產品類的實例,客戶端能夠免除直接建立產品對象的責任,而僅僅「消費」產品;簡單工廠模式經過這種作法實現了對責任的分割,它提供了專門的工廠類用於建立對象。
客戶端無須知道所建立的具體產品類的類名,只須要知道具體產品類所對應的參數便可,對於一些複雜的類名,經過簡單工廠模式能夠減小使用者的記憶量。
經過引入配置文件,能夠在不修改任何客戶端代碼的狀況下更換和增長新的具體產品類,在必定程度上提升了系統的靈活性。
因爲工廠類集中了全部產品建立邏輯,一旦不能正常工做,整個系統都要受到影響。
使用簡單工廠模式將會增長系統中類的個數,在必定程序上增長了系統的複雜度和理解難度。
系統擴展困難,一旦添加新產品就不得不修改工廠邏輯,在產品類型較多時,有可能形成工廠邏輯過於複雜,不利於系統的擴展和維護。
簡單工廠模式因爲使用了靜態工廠方法,形成工廠角色沒法造成基於繼承的等級結構。
模式適用環境
在如下狀況下可使用簡單工廠模式:
工廠類負責建立的對象比較少:因爲建立的對象較少,不會形成工廠方法中的業務邏輯太過複雜。
客戶端只知道傳入工廠類的參數,對於如何建立對象不關心:客戶端既不須要關心建立細節,甚至連類名都不須要記住,只須要知道類型所對應的參數。
小結
建立型模式對類的實例化過程進行了抽象,可以將對象的建立與對象的使用過程分離。
簡單工廠模式又稱爲靜態工廠方法模式,它屬於類建立型模式。在簡單工廠模式中,能夠根據參數的不一樣返回不一樣類的實例。簡單工廠模式專門定義一個類來負責建立其餘類的實例,被建立的實例一般都具備共同的父類。
簡單工廠模式包含三個角色:工廠角色負責實現建立全部實例的內部邏輯;抽象產品角色是所建立的全部對象的父類,負責描述全部實例所共有的公共接口;具體產品角色是建立目標,全部建立的對象都充當這個角色的某個具體類的實例。
簡單工廠模式的要點在於:當你須要什麼,只須要傳入一個正確的參數,就能夠獲取你所須要的對象,而無須知道其建立細節。
簡單工廠模式最大的優勢在於實現對象的建立和對象的使用分離,將對象的建立交給專門的工廠類負責,可是其最大的缺點在於工廠類不夠靈活,增長新的具體產品須要修改工廠類的判斷邏輯代碼,並且產品較多時,工廠方法代碼將會很是複雜。簡單工廠模式適用狀況包括:工廠類負責建立的對象比較少;客戶端只知道傳入工廠類的參數,對於如何建立對象不關心。