現實中的工廠負責生產產品,顧名思義,編程中的簡單工廠就是一個生產對象的類,它的主要做用是建立具體的產品類實例。咱們以一個生產鼠標爲例來分析簡單工廠的做用,鼠標有兩種:戴爾鼠標和惠普鼠標,代碼以下:編程
//鼠標抽象類 public abstract class Mouse { public abstract void Print(); } //戴爾鼠標 public class DellMouse : Mouse { public override void Print() { Console.WriteLine("生產了一個Dell鼠標!"); } } //惠普鼠標 public class HpMouse : Mouse { public override void Print() { Console.WriteLine("生產了一個惠普鼠標!"); } }
客戶端代碼:app
class Program { static void Main(string[] args) { Mouse mouse1 = new DellMouse(); Mouse mouse2 = new DellMouse(); Mouse mouse3 = new DellMouse(); Mouse mouse4 = new DellMouse(); Mouse mouse5 = new DellMouse(); mouse1.Print(); } }
程序運行以下:ide
咱們能夠看到程序運行沒有問題,經過new一個DellMouse咱們能夠建立一個戴爾的鼠標,這時有一個問題,若是咱們不想要戴爾鼠標了,要所有生產惠普鼠標怎麼辦呢?最簡單直接的方法就是把 new DellMouse所有替換成 new HpMouse 。若是咱們的軟件中new了100個DellMouse實例呢?一個一個地去替換會是一個巨大的工做量,同時經過new的方式來建立戴爾鼠標的實例,會讓DellMouse類和客戶端產生強耦合關係,這時候使用簡單工廠就能夠幫助咱們下降耦合,減小工做量了。添加一個MouseFactory簡單工廠類,這個工廠類專門來建立Mouse的實例:spa
/// <summary> /// 鼠標工廠類 /// </summary> public class MouseFactory { private Mouse mouse = null; public Mouse CreateMouse(string brand) { switch (brand) { case "dell": mouse = new DellMouse(); break; case "hp": mouse = new HpMouse(); break; default: break; } return mouse; } }
客戶端的代碼就能夠改爲:code
class Program { static void Main(string[] args) { //實例化一個工廠類 MouseFactory mouseFactory = new MouseFactory(); //經過工廠類建立鼠標 Mouse mouse1 = mouseFactory.CreateMouse("dell"); Mouse mouse2 = mouseFactory.CreateMouse("dell"); Mouse mouse3 = mouseFactory.CreateMouse("dell"); Mouse mouse4 = mouseFactory.CreateMouse("dell"); Mouse mouse5 = mouseFactory.CreateMouse("dell"); mouse1.Print(); Console.ReadKey(); } }
運行程序結果同樣的,這樣作有什麼好處呢?咱們看到咱們把之前的 new DellMouse() 替換成了 mouseFactory.Create("dell") ,客戶端和DellMouse的耦合變成了 客戶端<-->MouseFactory<-->DellMouse形式,有效下降了客戶端和DellMouse間的耦合。咱們還用一個疑問,程序改爲這樣的話,若是咱們想把戴爾鼠標所有換成惠普鼠標,要把工廠類的參數"dell"換成"hp",不是還要改100次?任務量沒有下降呀!對於這個問題,咱們能夠把品牌名brand存放在一個地方,如配置文件中,這樣咱們想切換鼠標品牌時就不用修改代碼,直接修改配置文件便可,以下:對象
配置文件:blog
<appSettings> <add key="dbname" value="dell"/> </appSettings>
工廠類修改成:繼承
/// <summary> /// 鼠標工廠類 /// </summary> public class MouseFactory { //從配置文件中讀取品牌 private static readonly string brand = ConfigurationManager.AppSettings["brand"]; private Mouse mouse = null; public Mouse CreateMouse() { switch (brand) { case "dell": mouse = new DellMouse(); break; case "hp": mouse = new HpMouse(); break; default: break; } return mouse; } }
客戶端代碼就不用傳參數了,以下:string
class Program { static void Main(string[] args) { //實例化一個工廠類 MouseFactory mouseFactory = new MouseFactory(); //經過工廠類建立鼠標 Mouse mouse1 = mouseFactory.CreateMouse(); Mouse mouse2 = mouseFactory.CreateMouse(); Mouse mouse3 = mouseFactory.CreateMouse(); Mouse mouse4 = mouseFactory.CreateMouse(); Mouse mouse5 = mouseFactory.CreateMouse(); mouse1.Print(); Console.ReadKey(); } }
如今咱們想把生產的鼠標都換成惠普鼠標,只須要將配置文件中的dell改爲hp便可,修改配置文件後運行結果以下:產品
大功告成!這時有一個問題,若是咱們想生產華碩鼠標怎麼辦呢?除了添加一個繼承Mouse的AsusMouse類外,還要在MouseFactory中添加一段case 代碼。按照開閉原則,添加一個實現類沒什麼問題,開閉原則中對添加開放;可是修改MouseFactory工廠類就違背了對修改閉合的原則了。後邊的工廠模式就是專門用來解決這個問題的。
上邊例子的類圖:
簡單工廠的優勢:
1.簡單工廠能夠有效地下降客戶端和具體對象的耦合,將new具體對象的任務交給了一個簡單工廠類
2能夠有效的進行代碼複用,如客戶端A和客戶端B都須要一個具體對象,客戶端A和客戶端B能夠經過同一個簡單工廠來獲取具體類型的實例
簡單工廠的缺點:
必定程度上違背了開閉原則,在新增產品時須要修改簡單工廠類