锁定老帖子 主题:探索设计模式之二——工厂方法模式
精华帖 (0) :: 良好帖 (1) :: 新手帖 (0) :: 隐藏帖 (1)
|
||||
---|---|---|---|---|
作者 | 正文 | |||
发表时间:2010-01-19
最后修改:2010-01-19
2.工厂方法模式(Factory Method Pattern)上一章介绍了简单工厂模式的作用和使用场景,它能为我们隔离开产品使用者与产品制造者的职责,使得这两部分代码脱离耦合。
在看到简单工厂模式带来的好处的同时,我们也可以预见,随着工厂产品的丰富,每增加一个产品,都将需要修改工厂方法。这是简单工厂的特性——只能处理可预见的情况决定的。然而,频繁的修改代码是我们所不愿意看到的,通过修改代码来增加产品(功能),也违反了设计模式中的“开闭原则” 。
开闭原则:即“开放-闭合原则”,软件架构应该设计成对于修改来说,代码实体是关闭的,而对于扩展来说,代码实体则是开放的。通俗一点讲,开闭原则是鼓励通过“新增”来代替“变化”。鼓励设计者将业务逻辑抽象化,将逻辑的本质设计成抽象类或者接口,逻辑的具体实践操作设计成具体实现类。
现实世界中,业务的本质是相对稳定的,而业务的具体实践则总会不断变化。在逻辑改变的时候,应当做到可以只替换具体实现类,而会不影响到代码的架构。开闭原则是OOAD中的核心原则,在实现功能需求的时候,新增的代码与修改的代码之间的比值,某种程度上可以作为量化衡量一个软件系统的成熟程度的标志。
为了解决简单工厂的这个弊端,需要引入本章的主题:工厂方法模式。工厂方法模式又称为工厂模式,也叫虚拟构造器(Virtual Constructor),工厂方法模式主要是对“工厂”的封装,提供一个创建者的接口,将产品实例化的步骤延迟到工厂的子类完成,让子类决定需要创建什么产品。
目的: 定义创建者的抽象接口,延迟产品实例化到其子类之中,创建的产品一般不再通过传入参数控制,而直接决定于使用了哪个实现类作为其子类。
场景: 随着游戏的发展,只靠机枪兵、喷火兵越来越难以获得战斗胜利了。这时候,机械化的重型武器登上了战争的舞台,战场上的主角,不再只是从兵营一个地方生产出来。司令部为了检验Raynor的设计模式是否能在机械化混合部队中发挥作用,特别举行了一次阅兵仪式……
为了简单起见,本次阅兵需要检阅仅两种部队:从兵营生产出来的机枪兵以及从重工厂生产出来的坦克。无论从哪里生产出来,他们都是Terran的部队,实现了ITerranArmy接口,对于本次阅兵来说,此接口只有一个showState()方法。
分析:
照例,我们先看一下这次需要涉及到的产品类图及代码: 图2.1 战斗部队及工厂的UML图
如果现在继续使用简单工厂来完成这个需求的话,随着各种兵种的登场,工厂类的代码将会出现一长串的if语句,而且每增加一种兵种,就必须修改一次工厂类。显然,根据上面的讨论,这样的代码是不可忍受的。
根据当前的实际情况,Raynor对简单工厂做出了一些扩展:首先建立后勤部,它不负责生产任何部队,但是任何部队的生产都是由后勤部直接领导,在程序语言中,我们把它叫做“抽象工厂”,在本次实例中,我们把它叫做“ITerranFactory”接口,无论是兵营还是重工厂,都是此接口的一个实现类,在程序语言中,我们把这些实现类叫做“具体工厂”。而场景描述中提到的ITerranArmy接口,在程序语言中则成为“抽象产品”,要生产的机枪兵、坦克都是此接口的实现,成为“具体产品”。
抽象工厂和具体工厂的实现代码如下:
在阅兵的时候,调用代码如下:
从代码上可以看出,我们需要什么产品,不再是靠外界传入参数决定,而是取决于抽象工厂使用的是具体哪个实现类。
值得指出的是,虽然示例代码中是直接通过new来创建具体工厂,但在现实编程中,大部分工厂方法模式都是配合这反射来使用的,既可以考虑把“SoldierFactory”、“MachineFactory”等具体实现类写在配置文件中,通过反射代替直接new一个具体工厂对象,这样当增加一个产品,就可以做到对工厂和使用者都不存在任何修改,只需要添加一个新的工厂类,并且配置到配置文件中即可,这就是开闭原则的一个体现。
最终运行结果如下:
总结: 通过上述阅兵的例子,我们看到工厂方法模式确实给系统架构带来强大而灵活的扩展能力。这种基于多态性设计的模式,使得产品的实例化延迟到具体子类之中,通过替换不同的实现子类就能达到新增和切换产品的目的。
由于本次阅兵效果良好,司令部决定让Raynor领导这些部队对Zerg进行一次大规模的协同作战。前面在简单工厂、工厂方法两种模式中,主要都是围绕这个体产品(Marine、Firebat、Tank等)的创建进行讨论,下一章中,我们将会通过一次“协同作战”看看各种具体对象之间存在互相依赖关系时,如何运用抽象工厂模式(Abstract Factory Pattern)来解决问题。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
||||
返回顶楼 | ||||
发表时间:2010-01-19
PDF下载见附件,《设计模式探索——星际争霸探险之旅》其他章节请见我博客:
http://icyfenix.iteye.com |
||||
返回顶楼 | ||||
发表时间:2010-01-31
写的很好 ,但是例子举的不好,不够简洁
|
||||
返回顶楼 | ||||
浏览 4786 次