探索设计模式之一——简单工厂模式
探索设计模式
通过一个外界参数来选择不同类的实例。
图1.1 战斗部队(产品)的UML图
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(); }}?
结果只能考验运气,运气不好的时候,下场那是相当的凄凉……

?图 1.2
显然,以固定的业务逻辑应付不断的业务变化是不可能完成任务的。为了掌握主动,夺取胜利,我们必须根据不同的敌人来选择不同的战士,现在,代码变成这样:
// 战斗场景2 public static void scene2() { ITerranSoldier[] solder = new ITerranSoldier[5]; for (int i = 0; i < 5; i++) { int enemy = meetEnemy(); if (enemy == Const.Zergling) { solder[i] = new Firebat(); } else { solder[i] = new Marine(); } solder[i].attackEnemy(enemy); } }?// 首先增加一个士兵训练工厂public class SoldierFactory { public ITerranSoldier create(int enemy) { if (enemy == Const.Zergling) { return new Firebat(); } else { return new Marine(); } }} // 战斗场景3 public static void scene3() { // 定义一个兵营为“士兵工厂”,这也符合现实逻辑 SoldierFactory Barrack = new SoldierFactory(); ITerranSoldier[] solder = new ITerranSoldier[5]; for (int i = 0; i < 5; i++) { int enemy = meetEnemy(); solder[i] = Barrack.create(enemy); solder[i].attackEnemy(enemy); } }?
图 1.3
同时,Raynor使用了设计模式,在小规模战斗中表现出色,升级为更高级军官,掌握更多的战斗部队,面对更多不同的敌人时候,简单工厂的缺点就逐渐显露出来:譬如只能根据事先考虑到的敌人来只能创建事先考虑到的部队、譬如随着机械化部队的加入,要通过单一的一个工厂来生产产品就显得无能为力……且看下一章,如何使用工厂方法模式(Factory Method Pattern)来解决这些问题。
[1] 《星际争霸》:著名电子竞技游戏。如果你接触过《星际争霸》这款游戏,那学习到知识的同时将会获得游戏的乐趣,而没有接触过《星际争霸》的话也没关系,没有游戏背景完全不影响对此系列文章的阅读。
?
1 楼 IcyFenix 2010-01-19 PDF下载见附件,《设计模式探索——星际争霸探险之旅》其他章节请见我博客:http://icyfenix.iteye.com 2 楼 kimmking 2010-01-19 IcyFenix 写道PDF下载见附件,《设计模式探索——星际争霸探险之旅》其他章节请见我博客:
http://icyfenix.iteye.com
这些文章05年就有了
lz是转帖吗?
如果是为什么没有注明出处??
http://terrylee.cnblogs.com/archive/2006/02/21/334911.html 3 楼 IcyFenix 2010-01-19 kimmking 写道IcyFenix 写道PDF下载见附件,《设计模式探索——星际争霸探险之旅》其他章节请见我博客:
http://icyfenix.iteye.com
这些文章05年就有了
lz是转帖吗?
如果是为什么没有注明出处??
http://terrylee.cnblogs.com/archive/2006/02/21/334911.html
谢谢关注。
文章是原创的,还打算连载下去。 4 楼 kimmking 2010-01-20 那就,支持lz
感谢分享,06年的时候,我也讲过一段时间设计模式。
有时间可以交流下。 5 楼 li445970924 2010-01-21 写的好 关 注 中.... 6 楼 wandou 2010-01-22 想问楼主一个问题:
ITerranSoldier soldier=new SoliderFactory.create(enemy)
与
ITerranSoldier soldier= enemy==Const.Zergling?new Firebat(): new Marine();
这两种写法有何区别?引入这个工厂,有何好处?这个工厂真的是必须的吗? 7 楼 IcyFenix 2010-01-22 wandou 写道想问楼主一个问题:
ITerranSoldier soldier=new SoliderFactory.create(enemy)
与
ITerranSoldier soldier= enemy==Const.Zergling?new Firebat(): new Marine();
这两种写法有何区别?引入这个工厂,有何好处?这个工厂真的是必须的吗?
你好,文中提到的这段话:
我们无法分辨Raynor到底是一个战队小队指挥官还是后勤部长?一个战场指挥官的职责是关心士兵如何战斗,而不是去关心士兵装备的是机枪还是喷火器,那是后勤部长的职责!如果将这两项职责混合到同一个人(同一段代码)中,日后无论是遇到新的敌人(业务逻辑的改变),还是有了新的士兵或者士兵要装备新的装备(产品的增加和产品变化)都需要修改这段代码。
只有Firebat和Marine两个兵种的话可能看不出差别,但是区分职责还是应当的,试想日后发展到有十几二十个兵种可供选择呢?如果下面一种写法创建的地方很多,发现需要增加或者减少一种兵种的时候是不是也麻烦? 8 楼 jordan421 2010-01-25 没有顿开茅塞的感觉,看来还需要修炼。 9 楼 wangzz_850729 2010-03-12 想问楼主一个问题:
简单工厂模式和工厂模式在MVC开发中最常用的地方,和方法是什么啊? 10 楼 once_more 2010-05-08 以前学习的时候感觉有点不解,看完LZ的文章,清晰不少 11 楼 dingherry 2010-05-14 Const.Zergling
是什么意思?需要定义Zergling吗?在哪定义? 12 楼 SmallMin 2011-08-07 wandou 写道想问楼主一个问题:
ITerranSoldier soldier=new SoliderFactory.create(enemy)
与
ITerranSoldier soldier= enemy==Const.Zergling?new Firebat(): new Marine();
这两种写法有何区别?引入这个工厂,有何好处?这个工厂真的是必须的吗?
引入工厂的好处在与,工厂封装了创建对象的逻辑。这里体现了单一职责的原则。在业务逻辑的代码中将对象创建的职责分离到工厂去,类的内聚性会提高。而且,对于修改来说,若增加了一种Const.Zergling,在统一的工厂中修改更加适合。 13 楼 dfwang 2011-09-28 感谢bz,收益匪浅