读书人

探索设计形式之三抽象工厂模式

发布时间: 2012-10-31 14:37:32 作者: rapoo

探索设计模式之三——抽象工厂模式
3.抽象工厂模式(Abstract Factory Pattern)

创建一系列互相关联或者互相以来的组合产品。

?

随着游戏的发展,前期小打小闹的试探进攻时期已经过去。我们要考虑的问题也已经不再是一个机枪兵能否战胜一只小狗、一个火兵能否打赢一只刺蛇(见简单工厂模式)了。游戏中期要占得先机,关键不在一兵一卒,而在战术正确与否。

?

星际争霸多年的游戏发展中,出现过无数天马行空的战术和激动人心的战例。其中,在Terran在对抗Terran和Zerg时,有两种主流战术如下:

?

TvT:主力兵种使用坦克,维护兵种是SCV,空军选择Wraith(隐飞)

TvZ:主力兵种使用枪兵,维护兵种是Medic(护士),空军选择Science Vessel(科学球)

照例,我们先看一下这次需要涉及到的工厂和产品类图及代码:

图3.1 战斗部队及工厂的UML图

public interface IAttackUnit {    // 主攻单位有attack技能    public void attack();} public interface IAirUnit {    // 空中单位有assist技能    public void assist();} public interface IMedicalUnit {    // 医疗单位有cure技能    public void cure();} public class Marine implements IAttackUnit {    public Marine() {        System.out.println("制造出一个枪兵。");    }    public void attack() {        System.out.println("机枪兵作为主攻兵种,适合应付小体积单位,作战灵活,能被护士MM治疗。");    }} public class Medic implements IMedicalUnit {    public Medic() {        System.out.println("制造出一个护士。");    }    public void cure() {        System.out.println("护士能给生物部队快速恢复生命值,对机械部队着无能为力。");    }} public class ScienceVessel implements IAirUnit {    public ScienceVessel() {        System.out.println("制造出一个科学球。");    }    public void assist() {        System.out.println("科学球作为辅助单位,能侦查隐性单位,能使用辐射技能对目标造成伤害。");    }} public class SCV implements IMedicalUnit {    public SCV() {        System.out.println("制造出一个SCV。");    }    public void cure() {        System.out.println("SCV能修理坦克,但是对机枪兵等生物部队无能为力。");    }} public class Tank implements IAttackUnit {    public Tank() {        System.out.println("制造出一辆坦克。");    }    public void attack() {        System.out.println("坦克作为主攻兵种,适合应付大体积单位,威力强大,能比被SCV修理。");    }} public class Wraith implements IAirUnit {    public Wraith() {        System.out.println("制造出一架隐性飞机。");    }    public void assist() {        System.out.println("隐飞作为辅助单位,有优秀的侦查性能和很高的机动性。");    }} 
?

public interface IArmyFactory {    // 创建空军单位    public IAirUnit createAirUnit();    // 创建医疗单位    public IMedicalUnit createMedicalUnit();    // 创建主攻单位           public IAttackUnit createAttackUnit();} public class TvTArmyFactory implements IArmyFactory {    public TvTArmyFactory() {        System.out.println("当前使用的战术可以应付TvT。");    }    // 空中单位是隐飞    public IAirUnit createAirUnit() {        return new Wraith();    }    // 主攻单位是坦克    public IAttackUnit createAttackUnit() {        return new Tank();    }    // 医疗单位是SCV    public IMedicalUnit createMedicalUnit() {        return new SCV();    }} public class TvZArmyFactory implements IArmyFactory {    public TvZArmyFactory() {        System.out.println("当前使用的战术可以应付TvZ。");    }    // 空中单位是科学球    public IAirUnit createAirUnit() {        return new ScienceVessel();    }    // 主攻单位是枪兵    public IAttackUnit createAttackUnit() {        return new Marine();    }    // 医疗单位是护士    public IMedicalUnit createMedicalUnit() {        return new Medic();    }}
?

public class WarField {    // 战斗场景    public static void warScene(IArmyFactory factory) {        factory.createAttackUnit().attack();        factory.createMedicalUnit().cure();        factory.createAirUnit().assist();    }     public static void main(String[] args) {        warScene(new TvTArmyFactory());        System.out.println();        warScene(new TvZArmyFactory());    }}
?

?

从代码上可以看出,每一个具体工厂的目的都不是创造单个的具体产品,而是过把整个产品家族(IAttackUnit、IAirUnit、IMedicalUnit)的所有具体产品都创造出来,这样各个具体产品之间的联系就通过一个具体工厂来体现。当需要新增一个产品家族,或者已有产品家族的构成成员发生变化的时候,影响也就局限在了某一个具体工厂之中。业务逻辑所依赖的都是抽象工厂和抽象产品,具体产品变化的影响就这样从业务逻辑中隔离开来。

?

这种通过依赖抽象类(或者接口)来削弱耦合、隔离变化点的方法,在设计模式中被总结为一个重要原则——依赖倒转原则:业务逻辑应该依赖于抽象类,而不应该依赖于具体实现类。“依赖倒转”中的“倒转”,指得就是人们直观思维之中,高层逻辑应当依赖与他下面的功能点分解,功能点分解又依赖于底层功能这种自上而下层层依赖的开发思想。这种开发思想中,任何底层的变化都有可能导致产生对上层的影响,同时,上层需求有改动的时候,又同样需要下层改动提供支持,这样当软件层次累计得越来越高的时候,变化就越来越可能引起上下层间的反复传递,导致严重的后果——牵一发而动全身。


探索设计形式之三——抽象工厂模式

图3.2 自上而下的依赖关系


探索设计形式之三——抽象工厂模式

?图3.3 依赖反转


探索设计形式之三——抽象工厂模式
?图 3.2 两种兵种组合

经过三章关于“工厂模式”的介绍,我们对通过工厂来创建产品,隐藏具体实现和创建细节的做法已经有了一定的了解。对象的产生,除了直接使用new和使用工厂封装外,还有几种其他方式。在这边Terran部队建设如火如荼的时候,且看看那边Zerg的发展情况如何,看看其他几种创建模式是如何在Zerg中发挥作用的。

1 楼 IcyFenix 2010-01-19 PDF下载见附件,《设计模式探索——星际争霸探险之旅》其他章节请见我博客:
http://icyfenix.iteye.com 2 楼 fengsage 2010-01-22 谢谢分享。能否这样理解,普通工厂模式是抽象工厂模式的一种特例?

楼主能否用项目实例来阐述下在哪些情况下运用相对应的设计模式? 3 楼 mingyang2013 2010-06-17 很不错,多谢楼主!有全部23种设计模式的下载吗?如有,请告知,谢谢。 4 楼 yuur369 2012-02-02 很简洁明了。。。但是初学者不一定能看懂。。要有一定项目实际经验的人才能快速理解。。。

读书人网 >软件开发

热点推荐