天天看點

設計模式——簡單工廠模式

目錄

  • 1. 簡介
  • 2. 示例
    • 2.1 電腦V1.0
    • 2.2 電腦V2.0
    • 2.3 程式類圖
  • 3. 總結分析
  • 4. 參考及源碼下載下傳

shanzm-2020年4月1日 22:18:49

簡單工廠模式(Simple Factory Pattern):定義一個工廠類,根據不同的參數,建立并傳回不同的類。其中這些類具有一個公共的父類或是一個接口。

簡單工廠模式不屬于GoF四人組提出的23種設計模式,它是最簡單的工廠模式。

簡單工廠模式包含類:

  • Factory:工廠類,内部有是個精通的方法,根據參數選擇建立的對象
  • Product:抽象産品類,其作為具體産品的父類,負責定義産品的公共接口
  • ConcreteProduct:具體産品類,有多個,都是繼承與抽象産品類,工廠就是建立該類對象

示例源于《大話設計模式》,通過一個簡單的四則電腦來逐漸的重構,最終通過簡單工廠實作一個簡單的四則電腦。

首先建立一個簡單的控制台項目,實作一個簡單的四則運算電腦功能

當提示使用者輸入兩個數字,并輸入一個四則運算符,實作計算功能

namespace Calculator
{
    public class Operation
    {
        public static double GetResult(double numA, double numB, string oper)
        {
            double result = 0;
            switch (oper)
            {
                case "+":
                    result = numA + numB;
                    break;
                case "-":
                    result = numA - numB;
                    break;
                case "*":
                    result = numA * numB;
                    break;
                case "/":
                    result = numB != 0 ? numA / numB : 0;
                    break;
            }
            return result;
        }
    }

     //讓業務邏輯和界面邏輯分離
     class Program
    {
        
        static void Main(string[] args)
        {
            try
            {
                Console.WriteLine("enter a number");
                double numA = Convert.ToDouble(Console.ReadLine());

                Console.WriteLine("enter another number");
                double numB = Convert.ToDouble(Console.ReadLine());

                Console.WriteLine("enter operation");
                string oper = Console.ReadLine();

                Console.WriteLine(Operation.GetResult(numA, numB, oper).ToString());
                Console.ReadKey();
            }
            catch (Exception e)
            {

                Console.WriteLine("error:" + e.Message);
                Console.ReadKey();
            }

        }
    }
}

           

電腦V1.0中使用類對業務邏輯進行封裝了

但是你若是要是想要添加一個新的運算符則要對

Operation

類進行修改

其實這樣是不安全的,萬一你添加新的運算符的時候把原來的運算符的操作代碼修改錯了

這樣豈不是對項目代碼很不安全!

是以你可以把所有的運算符分别單獨定義一個類,這樣你就可以随意添加和修改某一個新的運算符

但是這時候問題又來了,主程式怎麼判斷要建哪一個運算符的對象

是以需要一個

Factory

類來判斷建什麼對象

在工廠類中,我們使用裡氏原則(子類對象指派給父類變量)。

即:先聲明一個父類對象的變量,根據使用者輸入判斷建立什麼具體的運算符對象

工廠類,隻要有一個靜态方法,根據條件的傳回一個各種方法的父類對象。

代碼示例

//聲明Operation基類(使用接口也可以,使用抽象類也可以)
    public abstract class Operation
    {
        private double _numA;
        private double _numB;

        public double NumA { get; set; }
        public double NumB { get; set; }


        public abstract double GetResult()

    }

    //加法運算符
     public class OperationAdd : Operation
    {
        public override double GetResult()
        {
            double result = 0;
            result = this.NumA + this.NumB;
            return result;
        }
    }

    //減法運算符
     public class OperationSub : Operation
    {
        public override double GetResult()
        {
            double result = 0;
            result = this.NumA - this.NumB;
            return result;
        }
    }

    //乘法運算符
     public class OperationMul : Operation
    {
        public override double GetResult()
        {
            double result = 0;
            result = this.NumA * this.NumB;
            return result;
        }
    }

    //除法運算符
    public class OperationDiv : Operation
    {
        public override double GetResult()
        {
            double result = 0;
            if (this.NumB == 0)
            {
                throw new Exception("除數不為0!");
            }
            result = this.NumA / this.NumB;
            return result;
        }
    }


    //工廠類
     public class OperationFactory
    {
        public static Operation CreateOperation(string operation)
        {
            Operation oper = null;
            switch (operation)
            {
                case "+":
                    oper = new OperationAdd();
                    break;
                case "-":
                    oper = new OperationSub();
                    break;
                case "*":
                    oper = new OperationMul();
                    break;
                case "/":
                    oper = new OperationDiv();
                    break;
            }
            return oper;
        }
    }

    //主程式
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                Console.WriteLine("enter operation");
                string operation = Console.ReadLine();

                Operation oper = OperationFactory.CreateOperation(operation);

                Console.WriteLine("enter a number");
                oper.NumA = Convert.ToDouble(Console.ReadLine());

                Console.WriteLine("enter another number");
                oper.NumB = Convert.ToDouble(Console.ReadLine());

                double result = oper.GetResult();
                Console.WriteLine($"運算結果:{result.ToString()}");
                Console.ReadKey();

            }
            catch (Exception e)
            {

                Console.WriteLine("error:" + e.Message);
                Console.ReadKey();
            }
        }
    }
           

  • 優點:簡單工廠模式,使用工廠對象建立具體的産品對象,進而使得對象的使用和建立過程進行的分離。

    用戶端不需要關注對象是誰建立的,隻要通過工廠中靜态方法就可以直接擷取其需要的對象

  • 缺點:工廠類中需要選擇建立具體某個對象,是以一旦添加新的産品則必須要對工廠中的選擇邏輯進行修改,違背了開閉原則!
  • 适應場合:産品類相對較少的情況,使用簡單工廠建立産品對象,這樣即實作了生産者與消費者的分離,也不會在工廠類中出現太複雜的判斷邏輯!

  • 示例源代碼下載下傳
  • 設計模式——面向對象的設計原則
  • 《大話設計模式》

作者:shanzm

[email protected]

歡迎交流,歡迎指教!

繼續閱讀