首页 > 其他 > 详细

设计模式:03-抽象工厂(Abstract Factory)

时间:2014-03-11 05:43:30      阅读:450      评论:0      收藏:0      [点我收藏+]

在游戏场景的设计过程中,我们需要很多不同种类的场景,比如iphone上面很经典的一个游戏“忍者跳跃”相信大家都很熟悉吧。在该游戏场景中,有很多种场景,首先我们来考虑游戏中怪物类的设计,游戏开发者设计的类如图01:

bubuko.com,布布扣

在游戏中,需要创建Fox的类,这样就可以使用 Monster monster = new Fox() 这条语句来创建一个怪物的类。程序中所有需要Fox的类都会使用上述的代码进行创建。现在需求有改动,需要将Fox的怪物改成Stone,所有代码中出现 Monster monster = new Fox() 的语句都会相应的转变为 Monster monster = new Stone()。这么做的缺点有很多,首先改动的地方很多,不易完全改完,容易bug,后期的维护会越来越困难。其次,代码进行改动,需要游戏的重新编译部署,这些过程很繁琐,而且比较复杂。

鉴于上面的这么多缺点,于是乎,我们就会自然的想到,不是在代码中进行直接类的调用,而是通过一个函数来返回具体的类,这样,所有的改动都变化为只需要改动函数中的一个小部分,而不是代码中的全部内容。这样类的设计就可以如图02那样的设计。下面是相关实现的代码:

bubuko.com,布布扣
 1 public abstract class Monster {
 2 }
 3 
 4 public abstract class Fox {
 5 }
 6 
 7 public classs MonsterFactory {
 8     public static Monster getMonster() {
 9         return new Fox();
10     }
11 }
12 
13 Monster monster = MonsterFactory.getMonster();
bubuko.com,布布扣

上述的一个基本实现一般都被称之为静态工厂模式。

现在回到真正的游戏场景中,首先游戏场景中的元素包括:怪物(有比较多种类的小怪物还有一个大Boss),墙(其中包括阻碍物),人物。这些场景是一系列的元素的组合。比如在普通场景中,墙 + 怪物(狐狸、飞鸟、忍者、火龙)+障碍物,这些基本的元素共同组合成一个复杂的场景。如果按照静态工厂模式来进行软件构架的设计,那么就需要很多的辅助类,在代码的编写过程中也需要代码人员去维护一些列的组件,这样的设计对后期的维护可以说是个灾难。在这个案例中,面临的是“一系列相互倚赖对象的变化”,那么在软件的设计中,应该如何进行封装来避免这些多系列对象之间的紧耦合呢?

在《设计模式》那本书中,提供了一种设计模式——抽象工厂模式。

意图:提供一个接口,让接口负责创建一些列相关或者相互倚赖的对象,无需指定具体的类。

结构:

bubuko.com,布布扣

代码事例:

1、场景组件的相关类,对应上述图中的AbstractProuctA,AbstractProuctB这些类。

bubuko.com,布布扣
 1 /* 怪物 1 */
 2 public abstract class MonsterOne {
 3     public abstract void walk();
 4     public abstract int score();
 5 }
 6 
 7 public class CityAnamial extends MonsterOne {
 8     @Override
 9     public void walk() {};
10 
11     @Override
12     public int score() {};
13 }
14 
15 /* 怪物 2 */
16 public abstract class MonsterTwo {
17     public abstract void walk();
18     public abstract int score();
19 }
20 
21 public class CityStone extends MonsterTwo {
22     @Override
23     public void walk() { };
24 
25     @Override
26     public int score() { };
27 }
28 
29 /* 怪物 3 */
30 public abstract class MonsterBoss {
31     @Override
32     public abstract void walk() {};
33 
34     @Override
35     public abstract int score() {};
36 }
37 
38 public class CityBoss extends MonsterBoss{
39     @Override
40     public void walk() { };
41 
42     @Override
43     public int score() { };
44 }
45 
46 /**/
47 public abstract class Wall {
48     public abstract void color();
49 }
50 
51 public class CityWall extends Wall {
52     @Override
53     public void color() {};
54 }
55 
56 /* 人物 */
57 public abstract class Nim {
58     public abstract void run();
59 }
60 
61 public class CityNim extends Nim{
62     @Override
63     public void run(){};
64 }
bubuko.com,布布扣

2、对应的抽象工厂类,主要是对应的去创建具体的产品。

bubuko.com,布布扣
 1 /* 场景创建的类 */
 2 public abstract class SenceFactory {
 3     public abstract MonsterOne createMonsterOne();
 4     public abstract MonsterTwo createMonsterTwo();
 5     public abstract MonsterBoss createMonsterBoss();
 6     public abstract Wall createWall();
 7     public abstract Nim createNim();
 8 }
 9 
10 /* 城市场景相关组件的创建 */
11 public class CitySenceFactory extends SenceFactory {
12     @Override
13     public MonsterOne createMonsterOne() {
14         return new CityAnamial();
15     }
16 
17     @Override
18     public MonsterTwo createMonsterTwo() {
19         return new CityStone();
20     }
21 
22     @Override
23     public MonsterBoss createMonsterBoss() {
24         return new CityBoss();
25     }
26 
27     @Override
28     public Wall createWall() {
29         return new CityWall();
30     }
31 
32     @Override
33     public Nim createNim() {
34         return new CityNim();
35     }
36 }
bubuko.com,布布扣

3、一个简单的使用方法。

bubuko.com,布布扣
 1 public class GameManager {
 2     SenceFactory secefactory;
 3 
 4     public GameManager(SenceFactory sencefactory) {
 5         this.sencefactory = sencefactory;
 6     }
 7 
 8     public void buildGame() {
 9         MonsterOne monsterone = sencefactory.createMonsterOne();
10         MonsterTwo monstertwo = sencefactory.createMonsterTwo();
11         MonsterBoss monsterboss = sencefactory.createMonsterBoss();
12         Wall wall = sencefactory.createWall();
13         Nim nim = sencefactory.createNim();
14     }
15 }
bubuko.com,布布扣

使用总结:

1、如果需求中不需要应对“一系列组件的变化”,就不需要使用抽象工厂模式。

2、“系列对象”指的是这些对象相互作用和相互倚赖的关系,比如游戏开发中的各种物件。

3、 抽象工厂主要应对的是“新系列”需求的变化,无法应对“新的对象”需求的变化。比如在上面的案例中,如果需要在添加一个怪物,这时候抽象工厂的方法就很难应对这种状况。

4、为了解决上述“新需求”的变化,抽象工厂模式经常和工厂方法(Factory Method)结合起来一起使用。

设计模式:03-抽象工厂(Abstract Factory),布布扣,bubuko.com

设计模式:03-抽象工厂(Abstract Factory)

原文:http://www.cnblogs.com/hanzejl/p/3590892.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!