学习大话设计模式也有一段时间了,但是还没来得及总结,不是不想总结,而是一看这本书就刹不住闸了,大话设计模式是作者通过故事讲述程序如何设计的方法集。书中的主人公小菜和大鸟是全书的核心人物,小菜是一个新手,总是遇到各种各样的问题,而文中的大鸟也总能通过生活中的事来反映为一个个的设计模式。生动形象并且贴近生活,每一个故事都很有趣,这也是我看的第一本能让我笑得出来的编程书,这种写书方式,真的很让人乐意去看,去品味。
一、简单工厂模式
第一章介绍的就是最基本的简单工厂模式,书中以计算器的功能为例,运用简单工厂模式来减少客户端的代码,从而减少对于客户端代码的修改,去除了与具体产品的依赖。具体的类图如下:
简单工厂核心代码:
namespace ConsoleApplication3
{
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;
}
}
}
简单工厂确实是减少了客户端代码的压力,将Switch的判断语句封装到了工厂类里,但简单工厂的缺点也是显而易见的,如果要添加其他运算符,则需要修改简单工厂类,这样就违背了开放-封闭原则。开放-封闭原则说的是:对于扩展开放,对于更改封闭。简单工厂模式只是一个铺垫,作者也在这里留下了悬念,要想知道该如何改进,请继续往下看吧。
二、工厂方法模式
工厂方法模式是简单工厂模式的一个改进,克服了简单工厂违背开放-封闭原则的缺点,同时保持了封装对象创建过程的优点。工厂方法模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。也就是将简单工厂抽象成一个接口,让子类的工厂去实现这个接口的过程。
下面举个基本的数据访问程序的例子:
故事背景:本来写好了一个项目,是给一家企业做的网站,用SQL Server作为数据库,公司接到另一家公司类似需求的项目,但只能用Access数据库,这时需要修改原来项目的代码。
类图如下:
和简单工厂比较, 工厂方法模式将简单工厂中Switch语句的内容放到了子类中去实现,遵循了开放-封闭原则,保持了对象的封装。但是工厂方法模式也存在着不足,工厂方法模式实现时,客户端需要决定实例化哪一个工厂来实现数据访问,选择判断的问题还是存在的。工厂方法把简单工厂的内部逻辑判断移到了客户端代码来进行。要想加功能,本来是改工厂类,现在是修改客户端 。显然这样就不合适了。
三、抽象工厂模式
抽象工厂模式,提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。其实,个人感觉抽象工厂模式和工厂方法模式本质是一样的,都是将简单工厂的实例化延迟到子类中去。只是抽象工厂增加了新的工厂。仍以数据访问程序为例:
具体类图如下:
抽象工厂最大的好处就是易于交换产品系列,由于具体的工厂类,在一个应用中只需要在初始化的时候出现一次,使得在改变一个应用的具体工厂变得非常容易,只需要改变具体工厂即可使用不同的产品配置。如果你要更改数据库访问,我们只需要更改具体工厂就可以做到。当然了,抽象工厂也是有缺点的,如果要增加产品类,则需要修改工厂类,这样就违背了开放-封闭的原则。
总结:
设计模式的三大工厂都在围绕着开放-封闭原则和使客户端代码与创建实例过程分离两个方面来解决问题的。从简单工厂一步一步的改进,虽然到抽象工厂还不是最完美的解决办法。后面还有抽象工厂+反射来去除switch或if来解除分支判断带来的耦合。总之,设计模式都是前人思想和经验的结晶,还需要继续钻研!