1.简单工厂实现计算器
代码(简单工厂与工厂方法公共代码)
//Operaation运算类
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;
}
}
简单工厂类
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();
Console.WriteLine("结果是" + result);
用以上的代码程序就可以直接运行出结果3,但是我觉得这不能实现计算机的功能,要计算应该让用户自己输入数字和符号,于是我把客户端的代码,改为了如下代码
try
{
Operation oper;
Console.Write("请选择运算符号(+、-、*、/):");
oper = OperationFactory.createOperate(Console.ReadLine());
Console.Write("请输入数字A:");
oper.NumberA = Convert.ToDouble(Console.ReadLine());
Console.Write("请输入数字B:");
oper.NumberB = Convert.ToDouble(Console.ReadLine());
double result = oper.GetResult();
Console.WriteLine("结果是:" + result);
Console.ReadLine();
}
catch (Exception ex)
{
Console.WriteLine("您输入有错:" + ex.Message);
}
运行结果如下
简单工厂的优点:工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类,对于客户端来说,去除了与具体产品的依赖。
就像上面的计算器的例子,将要运算的数字和运算符号分离开,客户端不用写出使用某种符号的具体方法,而只要选择“+、-、*、/”中的一种符号给工厂,工厂自己就给出相应的实例,选择好运算符。
简单工厂的缺点:如果再添加一种运算方法就要对简单工厂类进行修改,也就是再添加新的case;修改原有的类,违背了开放封闭原则。
2.工厂方法模式实现计算器
//先构建一个工厂接口
interface IFactory
{
Operation createOperation();
}
class AddFactoy : IFactory//加法类工厂
{
public Operation CreateOperation()
{
return new OperationAdd();
}
}
减、乘、除类类似就不再一一写出,客户端代码如下
IFactory operFactory=new AddFactoy ();
Operation oper = operFactory.createOperation();
oper.NumberA = 1;
oper.NumberB = 2;
double result = oper.GetResult();
Console.WriteLine("结果是" + result);
工厂方法模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
就像上面的例子先定义一个创建运算符接口,然后再分别实现。
与简单工厂对比:解决了简单工厂与分支耦合的问题,根据依赖倒转原则,把工厂类抽象出一个接口,这个接口只有一个方法,就是创建抽象产品的工厂方法。然后,所有的要生产具体类的工厂就去实现这个接口,这样,一个简单工厂模式的工厂类,变成了一个工厂抽象接口和多个具体乘除对象的工厂,于是我们要增加运算方法时,就不需要更改原有的工厂类了,只需要增加此功能的运算类和相应的工厂类就可以了。