簡單工廠模式(Simple Factory Pattern):定義一個工廠類,根據不一樣的參數,建立並返回不一樣的類。其中這些類具備一個公共的父類或是一個接口。html
簡單工廠模式不屬於GoF四人組提出的23種設計模式,它是最簡單的工廠模式。git
簡單工廠模式包含類:github
Factory:工廠類,內部有是個精通的方法,根據參數選擇建立的對象設計模式
Product:抽象產品類,其做爲具體產品的父類,負責定義產品的公共接口安全
ConcreteProduct:具體產品類,有多個,都是繼承與抽象產品類,工廠就是建立該類對象ide
示例源於《大話設計模式》,經過一個簡單的四則計算器來逐步的重構,最終經過簡單工廠實現一個簡單的四則計算器。this
首先建立一個簡單的控制檯項目,實現一個簡單的四則運算計算器功能spa
當提示用戶輸入兩個數字,並輸入一個四則運算符,實現計算功能設計
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中使用類對業務邏輯進行封裝了code
可是你如果要是想要添加一個新的運算符則要對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(); } } }
優勢:簡單工廠模式,使用工廠對象建立具體的產品對象,從而使得對象的使用和建立過程進行的分離。
客戶端不須要關注對象是誰建立的,只要經過工廠中靜態方法就能夠直接獲取其須要的對象
缺點:工廠類中須要選擇建立具體某個對象,因此一旦添加新的產品則必需要對工廠中的選擇邏輯進行修改,違背了開閉原則!
適應場合:產品類相對較少的狀況,使用簡單工廠建立產品對象,這樣即實現了生產者與消費者的分離,也不會在工廠類中出現太複雜的判斷邏輯!