工廠方法模式 - OK

  工廠方法模式(Factory Method),定義了一個用於建立對象的接口,讓子類決定實例化哪個類。工廠方法使一個類的實例化延遲到子類。javascript

  工廠方法模式在實現時,客戶端須要決定實例化哪個工廠來實現運算類,選擇判斷的問題還存在,也就是說,工廠方法把簡單工廠的內部邏輯判斷移到了客戶端代碼來進行。想要加功能,原本是修改工廠類的,而如今是修改客戶端。html

  下面給出工廠方法模式UML圖:java

    

  工廠方法模式示例:git

複製代碼
namespace 工廠方法模式
{
    //數據庫類
    class DataBase
    {
        public virtual string SelectTopOne()
        {
            return "SELECT TOP 1 * FROM Table";
        }
    }

    //SQLServer類
    class SQLServer : DataBase
    {
        public override string SelectTopOne()
        {
            return "SELECT TOP 1 * FROM Table";
        }
    }

    //Oracle類
    class Oracle : DataBase
    {
        public override string SelectTopOne()
        {
            return "SELECT * FROM Table WHERE ROWRUM <= 1";
        }
    }

    //總結來講,下面的1個接口兩個類實現的就是簡單工廠中switch的功能
    //數據庫工廠
    interface IFactory
    {
        DataBase GetDataBase();
    }

    //SQLServer工廠
    class SQLServerFactory : IFactory
    {
        public DataBase GetDataBase() { return new SQLServer(); }
    }

    //Oracle工廠
    class OracleFactory : IFactory
    {
        public DataBase GetDataBase() { return new Oracle(); }
    }

    class Program
    {
        static void Main(string[] args)
        {
            IFactory factory = new SQLServerFactory();   //依賴於具體工廠類,但不依賴具體實現了了
            DataBase DB = factory.GetDataBase();         //從得到的工廠中 獲取學雷鋒對象
            Console.WriteLine(DB.SelectTopOne());

            //可是我有一種很強烈的感受,既然如此,何不這樣,雖然依賴了具體實現類,可是少了3個類
            //DataBase DB = new SQLServer();
            //Console.WriteLine(DB.SelectTopOne());

            Console.ReadKey();
        }
    }
}
複製代碼

  類圖以下:數據庫

  

  爲了對比與簡單工廠模式的區別,如下再寫個簡單工廠模式的來比較下:設計模式

複製代碼
namespace 簡單工廠
{
    public class Program
    {
        static void Main(string[] args)
        {
            DataBase DB = SimpleFactory.GetInstance("Oracle");
            Console.WriteLine(DB.SelectTopOne());

            DataBase DB2 = SimpleFactory.GetInstance("SQLServer");
            Console.WriteLine(DB2.SelectTopOne());

            Console.ReadKey();
        }
    }

    //簡單工廠類,判斷類,用於返回對應的的對象
    public class SimpleFactory
    {
        public static DataBase GetInstance(string type)
        {
            DataBase db = null;
            switch (type)
            {
                default:
                case "SQLServer":
                    db = new SQLServer();
                    break;
                case "Oracle":
                    db = new Oracle();
                    break;
            }
            return db;
        }
    }

    //基類
    public class DataBase
    { 
        public virtual string SelectTopOne()
        {
            return "SELECT TOP 1 * FROM Table";
        }
    }

    //實現類1
    public class SQLServer : DataBase
    {
        public override string SelectTopOne()
        {
            return "SELECT TOP 1 * FROM Table";
        }
    }

    //實現類2
    public class Oracle : DataBase
    {
        public override string SelectTopOne()
        {
            return "SELECT * FROM Table WHERE ROWRUM <= 1";
        }
    }
}
複製代碼

  比較一下,二者實現的代碼相似。ide

  對於簡單工廠模式,在客戶端方面,去除了對具體雷鋒的依賴,便可以不出現具體的雷鋒類(如大學生,社區志願者)。但若是要添加一個學雷鋒的中學生,就須要修改工廠類裏面的case判斷,以及添加一個具體類。post

  對於工廠方法模式,由客戶端方面來決定實例化哪個工廠來實現運算類,固然判斷的問題仍是存在。相比於簡單工廠,判斷的工做交到客戶端來處理。可是有一個好處,就是當須要添加一個DB2實現時,就沒有必要再修改原有的工廠類,只須要添加一個工廠類(這就是爲什麼這麼多工廠類,一個實現類就有一個工廠類),以及具體類(如例子中的SQLServer、Oracle)。this

  客戶端new的地方。相對於簡單工廠而言,對修改封閉了,符合開放封閉原則。可是帶來了代價就是類比較多(工廠類太多了,找死你)。spa

 
 
分類: 設計模式
 
0
0
 
(請您對文章作出評價)
 
« 上一篇: 代理模式 - OK
» 下一篇: 原型模式 - OK
相關文章
相關標籤/搜索