簡單工廠模式(設計模式02)

衣舞晨風發表於2016-03-15

作者:jiankunking 出處:http://blog.csdn.net/jiankunking

1、定義

簡單工廠模式(Simple Factory Pattern)屬於類的建立型模式,又叫靜態工廠方法模式(Static FactoryMethod Pattern),但不屬於23種GOF設計模式之一,是通過專門定義一個類來負責建立其他類的例項,被建立的例項通常都具有共同的父類。

2、基本簡介

簡單工廠模式的實質是由一個工廠類根據傳入的引數,動態決定應該建立哪一個產品類(這些產品類繼承自一個父類或介面)的例項。
該模式中包含的角色及其職責:
工廠(Creator)角色
簡單工廠模式的核心,它負責實現建立所有例項的內部邏輯。工廠類的建立產品類的方法可以被外界直接呼叫,建立所需的產品物件。

抽象產品(Product)角色
簡單工廠模式所建立的所有物件的父類,它負責描述所有例項所共有的公共介面。

具體產品(Concrete Product)角色
是簡單工廠模式的建立目標,所有建立的物件都是充當這個角色的某個具體類的例項。

UML圖(來自百度百科
UML圖

特點、:
1、只有一個工廠(具體的,沒有抽象)
2、只生產一種產品(抽象的產品)
3、這種產品可以有多種具體產品型別(派生)

工廠模式就相當於建立例項物件的new,我們經常要根據類Class生成例項物件,如A a=new A() 工廠模式也是用來建立例項物件的,所以以後new時就要多個心眼,是否可以考慮實用工廠模式,雖然這樣做,可能多做一些工作,但會給你係統帶來更大的可擴充套件性和儘量少的修改量。

比如:
在控制檯輸入兩個數還有要進行的是:+、-、*、/ 中的哪一種運算,那麼應該怎麼寫呢?

class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("請輸入第一個數字");
            int a = int.Parse(Console.ReadLine());

            Console.WriteLine("請輸入第二個數字");
            int b = int.Parse(Console.ReadLine());


            Console.WriteLine("請輸入運算子號");
            string op = Console.ReadLine();

            int result;

            //////////////////////////////

            Computer com = null;
            com = SimpleFactory.LoadComputer(op);


            com.NumberA = a;
            com.NumberB = b;
            result = com.Result;

            //////////////////////////////

            Console.WriteLine("{0}{1}{2}={3}", a, op, b, result);
        }



    }


    public static class SimpleFactory
    {
        /// <summary>
        /// 簡單的工廠的方法 
        /// *封裝了物件例項建立的複雜度
        /// </summary>
        /// <param name="op">用來區分具體產品的標識</param>
        /// <returns>產品的抽象</returns>
        public static Computer LoadComputer(string op)
        {
            Computer com = null;
            switch (op)
            {
                case "+":
                    com = new AddComputer();
                    break;
                case "-":
                    com = new JianComputer();
                    break;
                case "*":
                    com = new ChenComputer();
                    break;
                case "/":
                    com = new ChuComputer();
                    break;
                case "^":
                    com = new PowComputer();
                    break;
                default:
                    com = new AddComputer();
                    break;
            }

            return com;
        }
    }


    /// <summary>
    /// 運算
    /// </summary>
    public abstract class Computer
    {
        protected int _NumberA;

        public int NumberA
        {
            get { return _NumberA; }
            set { _NumberA = value; }
        }

        protected int _NumberB;

        public int NumberB
        {
            get { return _NumberB; }
            set { _NumberB = value; }
        }

        /// <summary>
        /// 子類必須完成的功能:計算結果並返回結果
        /// </summary>
        public abstract int Result
        {
            get;
        }
    }


    public class AddComputer : Computer
    {
        public override int Result
        {
            get
            {
                return base._NumberA + base._NumberB;
            }
        }
    }


    public class JianComputer : Computer
    {
        public override int Result
        {
            get
            {
                return base._NumberA - base._NumberB;
            }
        }
    }

    public class ChenComputer : Computer
    {
        public override int Result
        {
            get
            {
                return base._NumberA * base._NumberB;
            }
        }
    }
    public class ChuComputer : Computer
    {
        public override int Result
        {
            get
            {
                if (base._NumberB == 0)
                {
                    throw new ArgumentException("被除數不能為零");
                }
                return base._NumberA / base._NumberB;
            }
        }
    }

    public class PowComputer : Computer
    {
        public override int Result
        {
            get
            {
                return (int)Math.Pow(base._NumberA, base._NumberB);
            }
        }
    }

3、優缺點:

優點
工廠類是整個模式的關鍵.包含了必要的邏輯判斷,根據外界給定的資訊,決定究竟應該建立哪個具體類的物件.通過使用工廠類,外界可以從直接建立具體產品物件的尷尬局面擺脫出來,僅僅需要負責“消費”物件就可以了。而不必管這些物件究竟如何建立及如何組織的.明確了各自的職責和權利,有利於整個軟體體系結構的優化。

缺點
由於工廠類集中了所有例項的建立邏輯,違反了高內聚責任分配原則,將全部建立邏輯集中到了一個工廠類中;它所能建立的類只能是事先考慮到的,如果需要新增新的類,則就需要改變工廠類了。
當系統中的具體產品類不斷增多時候,可能會出現要求工廠類根據不同條件建立不同例項的需求.這種對條件的判斷和對具體產品型別的判斷交錯在一起,很難避免模組功能的蔓延,對系統的維護和擴充套件非常不利;
這些缺點在工廠方法模式中得到了一定的克服。

使用場景
工廠類負責建立的物件比較少;
客戶只知道傳入工廠類的引數,對於如何建立物件(邏輯)不關心;
由於簡單工廠很容易違反高內聚責任分配原則,因此一般只在很簡單的情況下應用。

小注:本文部分資料整理自網路,在此表示感謝。

相關文章