从计算器增加“开方”算法浅析简单工厂and工厂方法模式

未接触设计模式时,就知道有三个名字特别像的模式,即简单工厂、工厂方法、抽象工厂,那会儿我进度慢,看大家写的博客都晕了,不是前几天刚发了这个工厂吗?怎么又发?现在才分得清在设计模式中,“工厂三兄弟”的不同,而且如此重量级别的三个模式,更要好好去体会其中的玄机。

就从书中“计算器”的例子谈起,在简单工厂模式中,上一篇博客从可复用、可维护、可扩展的角度对其进行了分析,同时结合“六大原则”来看这个简单工厂模式,“单一职责”在具体的运算类中有体现,“开放-封闭原则”要比之前写在Main()函数中的代码优秀,但是问题也在这里,如果要添加新的算法的话,增加具体类的同时,要对方法工厂类OperationFactory中的case语句进行修改才OK,所以这一点做的不是特别好,有待改进,于是就引出了“工厂方法模式”。

下面来看二者在UML图上的区别:

简单工厂模式:

工厂方法模式:

一点点来看,在UML图中从具体的算法类开始,二者相同,然后为了可复用抽象出运算类,方法都为GetResult方法,紧接着就不同了,在简单工厂中,Only one简单工厂即OperationFactory,However在工厂方法中,定义了一个“抽象工厂”接口,接下来是具体的算法工厂类,这就是二者的不同,但是究竟是什么原因要从简单工厂模式的基础上衍生出工厂方法模式呢?

其实从增加运算类“开方”就能很好的解释这个问题。

Part 1、在简单工厂中实现增加运算类“开方”

首先增加具体的运算类那肯定是必须的,具体代码如下:

Class OperationExracting:Operation{ Public override double GetResult(){double result=0;result=NumberA*NumberB;return result; //这段代码在两个模式中是相同的<span style="white-space:pre"></span>}}

在此处对具体的运算类做完拓展之后需要在简单工厂中增加Case语句的分支,例如:

Case “√” oper = new OperationExracting();break;

就如上面所谈到的,对于“开放-封闭”原则,对扩展开放了,但是同时也对修改开放了,这样子就不好了嘛,虽然说简单工厂模式能够做到使得客户端不对具体的运算方法进行识别,但是在可扩展方面违反了“开闭”原则,这还是有点“丢了西瓜捡了芝麻”的韵味,So,如何去修改就该依靠该模式的升级版“工厂方法”来解决问题了。

Part 2、在工厂方法中实现增加运算类“开方”

前期代码都一样,仅仅是在算法工厂的地方定义了一个接口,then,,围绕接口进行编程,派生出具体的算法工厂类,如上UML图所示,代码的体现如下:Interface IFactory //构建接口工厂{Operation CreateOperation(); //仅有一个方法哦~~}Class AddFactory:IFactory //具体的加减乘除工厂类{Public Operation CreateOperation(){return new OperationAdd();<span style="white-space:pre"></span>}}

其实通过这段代码和在简单工厂中的OperationFactory代码对比就可以看出,前者将逻辑判断都写在了其中,后者则简单的定义了具体该去怎么做,没有逻辑判断的代码,需要客户端驱动,但是就“增加新的运算类”来说,无疑后者更加具有优势,这就是我想为什么要在“简单工厂”的基础上衍生出“工厂方法”的原因吧。

当然,对于让客户端是否需要认识具体的算法类,这看上去界面和逻辑代码耦合更紧,但是它能保证“开闭”原则不被违背,往往事情总是这么矛盾,我想单纯的去比较二者那个更好的话没有一点必要,毕竟具体问题需要具体分析,就像策略模式和简单工厂结合后所发挥的效应要远远超出二者任何一个模式单个的效应值,知道了二者各自的特点,能在应用中发挥出各自的优势就够了,就这些吧,在想自己就疯了,开心就好,生活是这样,学习也是这样。

(今天思路比较乱,请谅解)

像一颗深绿色的宝石镶嵌在云南大地上,

从计算器增加“开方”算法浅析简单工厂and工厂方法模式

相关文章:

你感兴趣的文章:

标签云: