简单工厂模式实现了一种"工厂"概念的面向对象设计模式,它可以在不指定对象具体类型的情况下创建对象。其实质是定义一个创建对象的接口,但让实现这个接口的类来决定实例化具体类。工厂方法让类的实例化推迟到子类中进行。
以书本上的计算器程序为例,其UML描述如下:
图中,AddOperator, SubtactOpertor继承算式基类Operator,而CreateOperator则是负责创建一个操作类,而不指明具体的子类类型。
下面,我们来看代码:
首先操作积累:
/// <summary>
/// 操作基类
/// </summary>
public class Operator
{
public decimal numLeft = 0;
public decimal numRight = 0;
public virtual decimal GetResult() { return 0; }
}
基类定义了两个操作数numLeft, numRight,然后定义一个虚方法GetResult(),以供在子类中重写来实现操作的多样性。
接着,我们实现两个子类:AddOperator, SubtractOperator:
加法类:AddOperator:
public class AddOperator : Operator
{
public override decimal GetResult()
{
return this.numLeft + this.numRight;
}
}
减法类:SubtractOperator:
public class SubtractOperator : Operator
{
public override decimal GetResult()
{
return this.numLeft - this.numRight;
}
}
最后,提供一个创建操作类CreateOperator, 里面有一个Create()用来返回Operator对象:
public static Operator Create(string strOperator)
{
Operator result = null;
switch (strOperator)
{
case "+":
result = new AddOperator();
break;
case "-":
result = new SubtractOperator();
break;
default:
result = new Operator();
break;
}
return result;
}
这样,一个简单的工厂方法模式就实现了,我们来写一下简单的测试代码:
static void Main(string[] args)
{
Operator opt = CreateOperator.Create("+");
opt.numLeft = 2;
opt.numRight = 3;
Console.WriteLine(opt.GetResult());
Operator opt1 = CreateOperator.Create("-");
opt1.numLeft = 10;
opt1.numRight = 2;
Console.WriteLine(opt1.GetResult());
Console.ReadKey();
}
运行可以看懂啊,前一个结果是2+3=5, 后一个是10-2=8.
那么:这是一个很简单的计算器例子,完全可以用几行代码一个函数就能实现,那为什么要这么大费周章的分成好几个类呢?
总结:我们写程序总要考虑可维护性、复用性、可扩展性和健壮性几个方面。假如我们使用一个方法来实现计算器的+、-、*、/,那么将后续我们需要添加新的操作符(如平方根)时,我们就需要来重新更改这个方法,那么之前已经稳定运行的+、-法运行程序也需要给暴露出来,说不定你在不经意间就更改了原先的代码逻辑,这就多多少少带来错误的可能性。
当我们将+、-、*、/几个运算分离出来时,就实现了这几个的运算分离。如果要新加一个操作,我们只需要新加一个操作类,然后再CreateOperator.Create()函数中新加一个Switch分支条件即可。这样就保证了之前的代码逻辑不受更改及影响,减少了错误的发生几率。
NOTE: 本系列是阅读《大话设计模式》一书的学习笔记,旨在记录、加深自己学习过程中的理解。