工廠模式

如今,若是我想要建立一個界面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

相關文章
相關標籤/搜索