一个简单工厂模式的小例子
“简单工厂模式根据提供的数据或者参数返回几个可能的类中的一个实例,说通俗点有点像面向对象编程中的多态性,一个基类,有多个派生类,在另外的调用程序中,根据参数来决定返回这个基类的哪个具体的派生类,返回值为基类类型,因为基类的引用可以指向派生类对象,而且这些所有的派生类都包含有基类的函数,也就是说派生类中有相同的函数,但是函数的实现可能不同”,引自aehyok的博文设计模式之二(简单工厂模式)前言
工厂模式中有: 工厂方法模式(Factory Method)模式和抽象工厂模式(Abstract Factory).
简单工厂模式是工厂方法模式的一个特例,理解简单工厂模式对于理解工厂模式很有意义
用简单工厂模式实现的"+","-","*","/",界面
\
实现接口(ICalculator),定义四个运算类"+","-","*","/"(CalculatorPlus、CalculatorMinus、CalculatorMultiply、CalculatorDivide),定义工厂类(FactoryCalculator)用以创建运算类对象。 类图
类代码
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace Calculator.简单工厂模式 8 { 9 /// <summary> 10 /// 接口-计算 11 /// </summary> 12 interface ICalculator 13 { 14 #region 计算方法+ float Calculate(float num1, float num2) 15 /// <summary> 16 /// 计算方法 17 /// </summary> 18 /// <param name="num1"></param> 19 /// <param name="num2"></param> 20 /// <returns></returns> 21 float Calculate(float num1, float num2); 22 #endregion 23 } 24 }
1 using Calculator.简单工厂模式; 2 using System; 3 using System.Collections.Generic; 4 using System.Linq; 5 using System.Text; 6 using System.Threading.Tasks; 7 8 namespace 简单工厂模式.Calculator 9 { 10 /// <summary> 11 /// 减法类 12 /// </summary> 13 class CalculatorMinus:ICalculator 14 { 15 #region 减法-float ICalculator.Calculate(float num1, float num2) 16 /// <summary> 17 /// 减法 18 /// </summary> 19 /// <param name="num1">第一个数</param> 20 /// <param name="num2">第二个数</param> 21 /// <returns></returns> 22 float ICalculator.Calculate(float num1, float num2) 23 { 24 return num1 - num2; 25 } 26 #endregion 27 } 28 }
1 using Calculator.简单工厂模式; 2 using System; 3 using System.Collections.Generic; 4 using System.Linq; 5 using System.Text; 6 using System.Threading.Tasks; 7 8 namespace 简单工厂模式.Calculator 9 { 10 /// <summary> 11 /// 加法类 12 /// </summary> 13 class CalculatorPlus:ICalculator 14 { 15 #region 加法-float ICalculator.Calculate(float num1, float num2) 16 /// <summary> 17 /// 加法 18 /// </summary> 19 /// <param name="num1">第一个数</param> 20 /// <param name="num2">第二个数</param> 21 /// <returns></returns> 22 float ICalculator.Calculate(float num1, float num2) 23 { 24 return num1 + num2; 25 } 26 #endregion 27 } 28 }
1 using Calculator.简单工厂模式; 2 using System; 3 using System.Collections.Generic; 4 using System.Linq; 5 using System.Text; 6 using System.Threading.Tasks; 7 8 namespace 简单工厂模式.Calculator 9 { 10 /// <summary> 11 /// 乘法类 12 /// </summary> 13 class CalculatorMultiply:ICalculator 14 { 15 16 #region 乘法-float ICalculator.Calculate(float num1, float num2) 17 /// <summary> 18 /// 乘法 19 /// </summary> 20 /// <param name="num1">第一个数</param> 21 /// <param name="num2">第二个数</param> 22 /// <returns></returns> 23 float ICalculator.Calculate(float num1, float num2) 24 { 25 return num1 * num2; 26 } 27 #endregion 28 } 29 }
1 using Calculator.简单工厂模式; 2 using System; 3 using System.Collections.Generic; 4 using System.Linq; 5 using System.Text; 6 using System.Threading.Tasks; 7 8 namespace 简单工厂模式.Calculator 9 { 10 /// <summary> 11 /// 除法类 12 /// </summary> 13 class CalculatorDivide:ICalculator 14 { 15 16 #region 除法-float ICalculator.Calculate(float num1, float num2) 17 /// <summary> 18 /// 除法 19 /// </summary> 20 /// <param name="num1">第一个数</param> 21 /// <param name="num2">第二个数</param> 22 /// <returns></returns> 23 float ICalculator.Calculate(float num1, float num2) 24 { 25 return (float)(num1 * 1.0) / num2; 26 } 27 #endregion 28 } 29 }
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 using 简单工厂模式.Calculator; 7 8 namespace Calculator.简单工厂模式 9 { 10 /// <summary> 11 /// 运算-工厂类 12 /// </summary> 13 class FactoryCalculator 14 { 15 #region 生成计算方法类+static ICalculator Create(string calculateMethod) 16 /// <summary> 17 /// 生成计算方法类 18 /// </summary> 19 /// <param name="calculateMethod">运算符</param> 20 /// <returns></returns> 21 public static ICalculator Create(string calculateMethod) 22 { 23 switch (calculateMethod)//根据选择的运算符,返回对应的类实例 24 { 25 case "+": 26 return new CalculatorPlus(); 27 case "-": 28 return new CalculatorMinus(); 29 case "*": 30 return new CalculatorMultiply(); 31 case "/": 32 return new CalculatorDivide(); 33 default: 34 return null; 35 } 36 } 37 #endregion 38 } 39 }
前台代码
1 using Calculator.简单工厂模式; 2 using System; 3 using System.Collections.Generic; 4 using System.ComponentModel; 5 using System.Data; 6 using System.Drawing; 7 using System.Linq; 8 using System.Text; 9 using System.Threading.Tasks; 10 using System.Windows.Forms; 11 12 namespace Calculator 13 { 14 public partial class frmCal : Form 15 { 16 public frmCal() 17 { 18 InitializeComponent(); 19 } 20 21 private void frmCal_Load(object sender, EventArgs e) 22 { 23 string[] calculateStr = { "+", "-", "*", "/" }; 24 cmbCalculate.Items.AddRange(calculateStr);//往cmbCulculate添加运算符 25 cmbCalculate.SelectedIndex = 0;//初始化未第一个运算符选项 26 } 27 28 //Calculator calculator;//定义计算方法字段 29 ICalculator iCalculator;//定义计算方法接口 30 private void btnCalculate_Click(object sender, EventArgs e) 31 { 32 float num1, num2;//参与运算的两个数值 33 float result;//运算结果 34 if (!float.TryParse(txtNum1.Text, out num1))//判断输入是否合法 35 { 36 MessageBox.Show("输入的第一个数不是数字"); 37 return; 38 } 39 if (!float.TryParse(txtNum2.Text, out num2))//判断输入是否合法 40 { 41 MessageBox.Show("输入的第二个数不是数字"); 42 return; 43 } 44 string calculateStr = cmbCalculate.SelectedItem as string;//获取选择的是什么运算方法 45 if (calculateStr != null)//运算符不为null 46 { 47 //switch (calculateStr) 48 //{ 49 // case "+": 50 // calculator = new CalculatorPlus(); 51 // case "-": 52 // calculator = new CalculatorMinus(); 53 // case "*": 54 // calculator = new CalculatorMultiply(); 55 // case "/": 56 // calculator = new CalculatorDivide(); 57 //} 58 //if (calculateStr == "+") 59 //{ 60 // calculator = new CalculatorPlus(); 61 //} 62 //if (calculateStr == "-") 63 //{ 64 // calculator = new CalculatorMinus(); 65 //} 66 //if (calculateStr == "*") 67 //{ 68 // calculator = new CalculatorMultiply(); 69 //} 70 //if (calculateStr == "/") 71 //{ 72 // calculator = new CalculatorDivide(); 73 //} 74 //result = calculator.Calculate(num1, num2);//计算结果 75 iCalculator = FactoryCalculator.Create(calculateStr);//根据运算符创建对应的运算类对象 76 result=iCalculator.Calculate(num1, num2);//计算结果 77 lblResult.Text = "计算结果:" + result;//显示计算结果 78 } 79 } 80 } 81 }
若果需要再扩展多个运算方法,只要再定义多个类实现ICalculator接口,扩展比较方便。也有其劣势,因为这样做需要修改工厂类,在其中添加相应的代码,若果要扩展的类数量多的话,简单工厂模式就显劣势。这时可以考虑用扩展性更强的工厂方法模式或抽象工厂模式