探索设计模式之一——简单工厂模式
探索设计模式
通过一个外界参数来选择不同类的实例。
图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下载见附件,《设计模式探索——星际争霸探险之旅》其他章节请见我博客: