如今,若是我想要建立一個界面View的實例須要調用View的構造函數:View view=new View();html
如今我想要建立3個不一樣的界面,分別是View1,View2,View3,那麼我將在另外一個類中調用它們的構造函數。編程
View1 view1 = new View1(); View2 view2 = new View2(); View3 view3 = new View3();
若是有更多的窗口呢?這樣公開的使用new操做符,很容易形成耦合問題。但若建立實例就必須使用new,那麼咱們如何更好的使用new呢?ide
簡單工廠函數
其實咱們再平時寫代碼時或許已經有了這樣的思想。這許多的View都有不少共同點,假設其中一個即是顯示窗口的名稱(固然這沒有什麼實際意義),咱們將其抽象爲一個接口IView,爲了方便,這裏的View就是單純的類,不是真正意義上的Window.spa
public interface IView { void Display(); }
public class View1 : IView { public void Display() { System.Console.WriteLine("界面1"); } }
public class View2 : IView { public void Display() { System.Console.WriteLine("界面2"); } }
public class View3 : IView { public void Display() { System.Console.WriteLine("界面3"); } }
而後咱們把全部實例的建立都放在ViewFactory中:3d
public class ViewFactory { public ViewFactory() { } public static IView CreateView(string viewName) { switch (viewName) { case "View1": return new View1(); case "View2": return new View2(); case "View3": return new View3(); default: return null; } } }
這樣即可按需(根據View的名字做爲參數)建立實例,並調用顯示名稱的方法:code
class Program { static void Main(string[] args) { ViewFactory.CreateView("View1").Display(); ViewFactory.CreateView("View2").Display(); ViewFactory.CreateView("View3").Display(); System.Console.ReadLine(); } }
運行結果:
htm
上面這個就是典型的簡單工廠模式了,其實咱們平時可能已經有了這樣的思想,只是並無進行更多的總結。經過簡單工廠,咱們將全部實例化封進另一個對象,同時經過多態實現了針對接口的編程,而不是直接針對具體類View1等。對象
若是此時,我還想再增長View4等等,我不只須要增長View4的界面,還必須修改ViewFactory,增長几句代碼:blog
case "View4": return new View4();
增長新界面就必須修改ViewFactory,這明顯違背了開-閉原則,這也是簡單工廠模式的缺點。
工廠方法模式
因爲簡單工廠違背了開閉原則,須要在簡單工廠的基礎上修改一下,就是工廠方法模式(Factory Method),與簡單工廠不一樣的是,建立對象不會集中在同一個類中,而是經過FactoryMethod方法在各個子類中分別實現相應對象的實例。
每一個View都會有本身獨立的Factory,如今將這多個Factory抽象爲接口IFactory:
public interface IFactory { IView GetView(); }
各個獨立的Factory,可取得對應的對象實例:
public class ViewFactory1 : IFactory { public IView GetView() { return new View1(); } }
public class ViewFactory2 : IFactory { public IView GetView() { return new View2(); } }
調用,只以View1爲例:
class Program { static void Main(string[] args) { IFactory factory = new ViewFactory1(); IView view = factory.GetView(); view.Display(); System.Console.ReadLine(); } }
結果:
若是須要新增一個View4,須要增長一個ViewFactory4和View4的類,可是沒必要修改已存在的其餘類。
抽象工廠
提供一個建立一系列相關或者事相互依賴對象的接口,而無需指定它們具體的類。
也就是說具體工廠生產相似的產品(這些產品繼承自統一父類),每個具體工廠可產生多種產品.好比,我這裏的一個抽象工廠可產生窗口和控件,紅色工廠可產生紅色的View和Control,綠色工廠可產生綠色的View和Control,但紅綠工廠產生的View都繼承自IView,Control繼承自IControl。
public abstract class AbstractFactory { public abstract IView CreateView(); public abstract IControl CreateControl(); }
以具體綠工廠爲例:
public class GreenFactory : AbstractFactory { public override IView CreateView() { return new GreenView(); } public override IControl CreateControl() { return new GreenControl(); } }
public class GreenView : IView { public void Display() { System.Console.WriteLine("綠色窗口"); } }
public class GreenControl : IControl { public void Display() { System.Console.WriteLine("我是 綠色工廠 生產出來的 綠色 控件。"); } }
紅色工廠相似我就再也不貼出代碼了,直接看一下調用:
class Program { static void Main(string[] args) { AbstractFactory.AbstractFactory factoryG = new GreenFactory(); IView viewG = factoryG.CreateView(); viewG.Display(); IControl controlG = factoryG.CreateControl(); controlG.Display(); System.Console.WriteLine(); AbstractFactory.AbstractFactory factoryR = new RedFactory(); IView viewR = factoryR.CreateView(); viewR.Display(); IControl controlR = factoryR.CreateControl(); controlR.Display(); System.Console.ReadLine(); } }
運行結果:
簡單工廠&工廠方法對比:
簡單工廠 | 工廠方法 | 抽象工廠 |
全部實例化在同一個類中實現,將對象封裝 | 建立一個接口,讓子類決定如何實現 | |
對象被封裝,違背開閉原則,彈性弱 | 將實例化延遲到子類 | 易膨脹,過於臃腫 |
參考連接:http://www.cnblogs.com/BoyXiao/archive/2010/05/06/1728808.html