由一个用C#语言编写的计算器控制台程序,来讲解简单工厂模式的应用
第一次做 程序代码如下:
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 (B == "/")
D = Convert.ToString(Convert.ToDouble(A) / Convert.ToDouble(C));
Console.WriteLine("结果是:" + D);
不足之处分析:1. string A string B string C 这样命名是非常不规范的 2. if(B == "+") if(B == “-”) ...判断分支,意味着每一个条件都要做判断,等于计算机做了三次无用功 3. D=Convert.ToString(Convert.ToDouble(A) / Convert.ToDouble(C)); 如果除数时,客户输入了0怎么办,如果用户输入的是字符符号而不是数字怎么办
第二次做 (解决上面三个问题,改进代码之后) 程序代码如下:
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);
}
不足之处分析:上面的程序不容易维护,不容易扩展,更不容易复用 {程序要做到: 可维护(要改只改要改的地方)可复用(该程序并非用完这一次就没有用了,完全可以在别的程序当中使用它)可扩展(若要添加,只需添加新的内容,并且原程序可以兼容这个内容)灵活性好(程序中各个模块可以相互调整位置,以满足业务上顺序))
第三次做 把业务逻辑与界面逻辑分开降低程序的耦合度(模块之间联系的紧密程序 附录一:高内聚低耦合)降低 程序代码如下:
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 "/":
if (numberB != 0)
result = numberA / numberB;
else
throw new Exception("除数不能为0。");
break;
}
return result;
}
}
客户端代码
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);
}
不足之处:如果程序要新添加一个开根号的运算,那程序员就需要扩充Operation类,此时程序员也可以去修改其他已经存在的运算如+、-这是不安全的,我们紧紧要添加一个开根号的运算,却把整个运算类交给了程序员,造成了安全隐患。
第四次做 通过封装、继承、多态并结合简单工厂模式,提高程序的可修改性,可扩展性,健壮性,以及安全性 程序代码如下:
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;
}
}
加减乘除类 (加减乘除类继承Operation运算类,重写了GetResult()方法,这样如果要修改一个算法,就不需要提供其他算法的代码了)
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;
}
}
简单运算工厂类 (如何去实例化特定的+、-、*、/对象呢? 简单工厂模式将解决这个问题 它声明了一个独立的类,利用多态去实例化具体的对象,这就是工厂)
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=null;
Console.Write("请输入运算符号(+、-、*、/):");
string strOperate = Console.ReadLine();
oper = OperationFactory.createOperate(strOperate);
Console.Write("请输入数字A:");
string strNumberA = Console.ReadLine();
oper.NumberA = Convert.ToDouble(strNumberA);
Console.Write("请输入数字B:");
string strNumberB = Console.ReadLine();
oper.NumberB = Convert.ToDouble(strNumberB);
string strResult = "";
strResult = Convert.ToString(oper.GetResult());
Console.WriteLine("结果是:" + strResult);
Console.ReadLine();
代码下载链接:http://download.youkuaiyun.com/detail/geekday/7622719 (该代码是用C#语言开发)
一个软件由多个子程序组成 一个子程序由多个模块构成 内聚就是构成子程序的各个模块之间的关系紧密程序 耦合就是各个子程序之间的关系紧密程度
正如我们这个计算器程序 由执行计算的部分+用户输入的部分两个子程序组成 那我们就要降低它们之间的关系紧密程序,就是让业务逻辑与界面逻辑分开 低耦合 执行计算的+ - * /部分关系的紧密程序要高一些,以便更好的完成计算操作 高内聚