锁定老帖子 主题:探索设计模式之一——简单工厂模式
精华帖 (1) :: 良好帖 (1) :: 新手帖 (0) :: 隐藏帖 (0)
|
|||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
作者 | 正文 | ||||||||||||||
发表时间:2010-01-19
最后修改:2010-01-19
探索设计模式——星际争霸探险之旅
第一部分:创建模式在GoF23种经典设计模式中,按照行为目的划分的话,可分为“创建模式”、“结构模式”、“行为模式”三大类别。这三大类23种设计模式,将会在《设计模式探索》中,随着Terran 与Zerg两个种族进行星际争霸[1]大战中,各个角色使用不同的设计模式来解决战场上各种各样的问题,一一展现设计模式在编程实践中,让代码变得优雅、健壮的魅力。
创建模式包括:
1.简单工厂模式(Simple Factory Pattern)严格来说,简单工厂模式并不属于GoF23种经典设计模式之一,但是简单工厂作为一个常用的编程习惯,在实际程序开发中经常被使用到,能为我们简单而有效的解决一些问题。同时,作为后续其他创建模式的引导,有必要先讲一下。
目的: 通过一个外界参数来选择不同类的实例。
场景: 在《星际争霸》中,Jim Raynor(游戏剧情中的人族英雄)现在担任一个Terran突击小分队的队长,在与Zerg的战斗中,执行侦查和歼灭落单敌人的任务。根据当前的敌军的兵种状况,Terran后勤部门能提供两种战斗部队:Marine(机枪兵)和Firebat(喷火兵),分别能对Zerg的Hydralisk(刺蛇)和Zergling(小狗)造成极大的伤害。但是如果顺序反过来,则喷火兵无法战胜刺蛇,机枪兵也无法战胜小狗。
分析:
先介绍两种战斗兵种的UML图和代码,本文后面讨论的“产品”就是指代他们。 图1.1 战斗部队(产品)的UML图
最初,Raynor直接向后勤部门申请了3个机枪兵和2个喷火兵的固定部队来面对战场的情况(战场用一个随机数字来模拟遇到的敌军)。如果用这种方式进行战斗的话……
public class WarField { // 随机模拟一个敌人 public static int meetEnemy() { return (int) Math.round(Math.random()); } // 战斗场景1 public static void scene1() { ITerranSoldier[] solder = new ITerranSoldier[5]; solder[0] = new Marine(); solder[1] = new Marine(); solder[2] = new Marine(); solder[3] = new Firebat(); solder[4] = new Firebat(); solder[0].attackEnemy(meetEnemy()); solder[1].attackEnemy(meetEnemy()); solder[2].attackEnemy(meetEnemy()); solder[3].attackEnemy(meetEnemy()); solder[4].attackEnemy(meetEnemy()); } public static void main(String[] args) { scene1(); } }
结果只能考验运气,运气不好的时候,下场那是相当的凄凉……
显然,以固定的业务逻辑应付不断的业务变化是不可能完成任务的。为了掌握主动,夺取胜利,我们必须根据不同的敌人来选择不同的战士,现在,代码变成这样:
这样的代码,看起来似乎能达到我们的目的,但是我们写代码,追求的不应当仅仅是解决一个具体问题,而是追求优雅和高质量的代码。当前,代码中一个很明显的问题就是,我们无法分辨Raynor到底是一个战队小队指挥官还是后勤部长?一个战场指挥官的职责是关心士兵如何战斗,而不是去关心士兵装备的是机枪还是喷火器,那是后勤部长的职责!如果将这两项职责混合到同一个人(同一段代码)中,日后无论是遇到新的敌人(业务逻辑的改变),还是有了新的士兵或者士兵要装备新的装备(产品的增加和产品变化)都需要修改这段代码。
在长期的生产实践之中的之中,有许多被实践证明有益的设计原则,其中有两条应该在写类似代码的时候想起:“简单职责原则:一个类负责一件事情,一个类应该只有一个能引起他变化的因素。”和“变化点隔离原则:如果一块代码不同地方都有可能经常发生改变,则说明它们应该分开封装,同时避免超大类、超大方法的产生。”
基于上面两个原则,我们应该把指挥官和后勤部长分开,各自完成自己的任务,代码变成这样:
现在的运行结果:
总结: 从上面一个如何构建5人突击小队的编码过程中,我们看到简单工厂模式的优点:隔离产品创建者和使用者,明确各自的职责,降低耦合度。简单工厂模式的应用场景:当使用者知道工厂需要的传入参数,并且对工厂如何生产出产品的逻辑并不关心。
简单工厂模式能为我们处理一些很经常遇到的代码场景,但同时要引用上文的一句话“以固定的业务逻辑应付不断的业务变化是不可能完成任务的”,设计模式也是如此,任何一个模式都不能解决所有的问题。现在游戏才刚刚开始,随着星际争霸战争过程的发展,后面将会遇到越来越复杂的场面。
同时,Raynor使用了设计模式,在小规模战斗中表现出色,升级为更高级军官,掌握更多的战斗部队,面对更多不同的敌人时候,简单工厂的缺点就逐渐显露出来:譬如只能根据事先考虑到的敌人来只能创建事先考虑到的部队、譬如随着机械化部队的加入,要通过单一的一个工厂来生产产品就显得无能为力……且看下一章,如何使用工厂方法模式(Factory Method Pattern)来解决这些问题。
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|||||||||||||||
返回顶楼 | |||||||||||||||
发表时间:2010-01-19
PDF下载见附件,《设计模式探索——星际争霸探险之旅》其他章节请见我博客:
http://icyfenix.iteye.com |
|||||||||||||||
返回顶楼 | |||||||||||||||
发表时间:2010-01-19
IcyFenix 写道 PDF下载见附件,《设计模式探索——星际争霸探险之旅》其他章节请见我博客:
http://icyfenix.iteye.com 这些文章05年就有了 lz是转帖吗? 如果是为什么没有注明出处?? http://terrylee.cnblogs.com/archive/2006/02/21/334911.html |
|||||||||||||||
返回顶楼 | |||||||||||||||
发表时间:2010-01-19
kimmking 写道 IcyFenix 写道 PDF下载见附件,《设计模式探索——星际争霸探险之旅》其他章节请见我博客:
http://icyfenix.iteye.com 这些文章05年就有了 lz是转帖吗? 如果是为什么没有注明出处?? http://terrylee.cnblogs.com/archive/2006/02/21/334911.html 谢谢关注。 文章是原创的,还打算连载下去。 |
|||||||||||||||
返回顶楼 | |||||||||||||||
发表时间:2010-01-20
那就,支持lz
感谢分享,06年的时候,我也讲过一段时间设计模式。 有时间可以交流下。 |
|||||||||||||||
返回顶楼 | |||||||||||||||
发表时间:2010-01-22
想问楼主一个问题:
ITerranSoldier soldier=new SoliderFactory.create(enemy) 与 ITerranSoldier soldier= enemy==Const.Zergling?new Firebat(): new Marine(); 这两种写法有何区别?引入这个工厂,有何好处?这个工厂真的是必须的吗? |
|||||||||||||||
返回顶楼 | |||||||||||||||
发表时间:2010-01-22
wandou 写道 想问楼主一个问题:
ITerranSoldier soldier=new SoliderFactory.create(enemy) 与 ITerranSoldier soldier= enemy==Const.Zergling?new Firebat(): new Marine(); 这两种写法有何区别?引入这个工厂,有何好处?这个工厂真的是必须的吗? 你好,文中提到的这段话: 我们无法分辨Raynor到底是一个战队小队指挥官还是后勤部长?一个战场指挥官的职责是关心士兵如何战斗,而不是去关心士兵装备的是机枪还是喷火器,那是后勤部长的职责!如果将这两项职责混合到同一个人(同一段代码)中,日后无论是遇到新的敌人(业务逻辑的改变),还是有了新的士兵或者士兵要装备新的装备(产品的增加和产品变化)都需要修改这段代码。 只有Firebat和Marine两个兵种的话可能看不出差别,但是区分职责还是应当的,试想日后发展到有十几二十个兵种可供选择呢?如果下面一种写法创建的地方很多,发现需要增加或者减少一种兵种的时候是不是也麻烦? |
|||||||||||||||
返回顶楼 | |||||||||||||||
发表时间:2010-01-25
没有顿开茅塞的感觉,看来还需要修炼。
|
|||||||||||||||
返回顶楼 | |||||||||||||||
发表时间:2010-03-12
想问楼主一个问题:
简单工厂模式和工厂模式在MVC开发中最常用的地方,和方法是什么啊? |
|||||||||||||||
返回顶楼 | |||||||||||||||
发表时间:2010-05-08
以前学习的时候感觉有点不解,看完LZ的文章,清晰不少
|
|||||||||||||||
返回顶楼 | |||||||||||||||
浏览 8305 次