您的位置:首页 > 其它

【设计模式】简单工厂模式——以一个简单的计算器为例

2015-12-04 13:51 836 查看
本文内容参考自《大话设计模式》(程杰 著)

注:以下代码为C#实现

1.拙劣的代码

class Program

{

static void Main(string[] args)

{

Console.Write("请输入数字A:");

string A = Console.ReadLine();

Console.Write("请选择运算符号(+、-、*、/):");

string B = Console.ReadLine();

Console.Write("请输入数字B:");

string C = Console.ReadLine();

string D = "";

if (B == "+")

D = Convert.ToString(Convert.ToDouble(A) + Convert.ToDouble(C));

if (B == "-")

D = Convert.ToString(Convert.ToDouble(A) - Convert.ToDouble(C));

if (B == "*")

D = Convert.ToString(Convert.ToDouble(A) * Convert.ToDouble(C));

if (O == "/")

D = Convert.ToString(Convert.ToDouble(A) / Convert.ToDouble(C));

Console.WriteLine("结果是:" + D);

}

}


毛病:命名不规范,判断分支做多次无用功,除数为0时出错,输入不是数字……

2.规范化

class Program

{

static void Main(string[] args)

{

try

{

Console.Write("请输入数字A:");

string strNumberA = Console.ReadLine();

Console.Write("请选择运算符号(+、-、*、/):");

string strOperate = Console.ReadLine();

Console.Write("请输入数字B:");

string strNumberB = Console.ReadLine();

string strResult = "";

switch (strOperate)

{

case "+":

strResult = Convert.ToString(Convert.ToDouble(strNumberA)

+ Convert.ToDouble(strNumberB));

break;

case "-":

strResult = Convert.ToString(Convert.ToDouble(strNumberA)

- Convert.ToDouble(strNumberB));

break;

case "*":

strResult = Convert.ToString(Convert.ToDouble(strNumberA)

* Convert.ToDouble(strNumberB));

break;

case "/":

if (strNumberB != "0")

strResult = Convert.ToString(Convert.ToDouble(strNumberA)

/ Convert.ToDouble(strNumberB));

else

strResult = "除数不能为0";

break;

}

Console.WriteLine("结果是:" + strResult);

Console.ReadLine();

}

catch (Exception ex)

{

Console.WriteLine("您的输入有错:" + ex.Message);

}

}

}


以上代码规范了,但是可重用性差!

3.业务的封装

Operation运算类

public class Operation

{

public static double GetResult(double numberA, double numberB, string operate)

{

double result = 0d;

switch (operate)

{

case "+":

result = numberA + numberB;

break;

case "-":

result = numberA - numberB;

break;

case "*":

result = numberA * numberB;

break;

case "/":

result = numberA / numberB;

break;

}

return result;

}

}


客户端代码

static void Main(string[] args)

{

try

{

Console.Write("请输入数字A:");

string strNumberA = Console.ReadLine();

Console.Write("请选择运算符号(+、-、*、/):");

string strOperate = Console.ReadLine();

Console.Write("请输入数字B:");

string strNumberB = Console.ReadLine();

string strResult = "";

strResult = Convert.ToString(Operation.GetResult(Convert.ToDouble(strNumberA),

Convert.ToDouble(strNumberB), strOperate));

Console.WriteLine("结果是:" + strResult);

Console.ReadLine();

}

catch (Exception ex)

{

Console.WriteLine("您的输入有错:" + ex.Message);

}

}


问题:如果我要增加其他运算,或者是想要修改运算的法则,那么其他代码都会受到影响,比如要重新编译,调试等等。

4.松耦合

Operation运算类

public class Operation

{

private double _numberA = 0;

private double _numberB = 0;

public double NumberA

{

get  {  return _numberA;  }

set  {  _numberA = value;  }

}

public double NumberB

{

get  {  return _numberB;  }

set  {  _numberB = value;  }

}

public virtual double GetResult()

{

double result = 0;

return result;

}

}


加减乘除类

class OperationAdd : Operation

{

public override double GetResult()

{

double result = 0;

result = NumberA + NumberB;

return result;

}

}

class OperationSub : Operation

{

public override double GetResult()

{

double result = 0;

result = NumberA - NumberB;

return result;

}

}

class OperationMul : Operation

{

public override double GetResult()

{

double result = 0;

result = NumberA * NumberB;

return result;

}

}

class OperationDiv : Operation

{

public override double GetResult()

{

double result = 0;

if (NumberB==0)

throw new Exception("除数不能为0。");

result = NumberA / NumberB;

return result;

}

}


在这里,我们定义了一个虚函数,然后其他运算继承操作类并实现该函数,这样子,如果要增加其他运算,只需要增加一个类来继承操作类就可以了,而且单个操作的修改完全不影响其他的运算!

5.简单工厂模式

使用上面代码之后,我们在客户端需要实例化相应的类,比如‘+’操作需要实例化OperationAdd,减操作需要实例化OperationSub,这样子暴露给客户的信息太多了,客户必须知道每个操作它对应的类!

使用简单的工厂模式可以避免这个问题:

简单运算工厂类

public class OperationFactory

{

public static Operation createOperate(string operate)

{

Operation oper = null;

switch (operate)

{

case "+":

oper = new OperationAdd();

break;

case "-":

oper = new OperationSub();

break;

case "*":

oper = new OperationMul();

break;

case "/":

oper = new OperationDiv();

break;

}

return oper;

}

}


客户端代码

Operation oper;

oper = OperationFactory.createOperate(“+”);

oper.NumberA = 1;

oper.NumberB = 2;

double result = oper.GetResult();


如果一来,客户端就简化了很多,它只需要知道 OperationFactory,并通过createOperate传入相应的操作就可以了!

当我们需要修改加法运算时,只需要修改OperationAdd,当我们需要增加其他运算时,只需要增加相应的运算子类,并在运算类工厂中增加分支即可。

同时,界面显示和我们的业务逻辑也是分离的~

UML图:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: