浅谈原型与抽象工厂

开发 开发工具
设计模式的书都很喜欢拿Prototype(原型)与Abstract Factory(抽象工厂)两个模式作比较,本文也为大家谈谈原型与抽象工厂。

从相似的角度来说,它们两个都通过Composite的方式,把实例化的过程从具体使用这些对象的类中分离出去,只让用户知道调用Manager或Factory的哪些方法来实例化而不用记住具体的类名。抽象工厂和原型模式是基于相同原理的模式,唯一的不同之处就是实例化的过程,抽象工厂是基于new来实例化对象的(缺点是HardCode,编译时已经决定了要实例化的具体是什么对象),而原型是基于Clone来创建对象的(优点是在程序运行时,能够像策略模式一样实时更换对象,创建出基于相同接口的不同对象。)我更倾向的观点把原型模式归为抽象工厂的一种具体实现形式,强调实例的创建时是基于另一个实例的Clone方法。

上面说了原型模式这么多好处。下面将按照《HeadFirst设计模式》的例子的改版来做一下解说。

场景:

你接了某个游戏公司的项目,项目为设计一个角色扮演游戏。在游戏中,当英雄在动态创建的场景中闯荡的时候,免不了要与各色各样的怪物来战斗。不仅有游戏公司预先定制好的怪物,而且还能够让高级玩家手动创造新的怪物(预先定义好的怪物的特征几乎都不一样,行为比用户自定义的怪物要多,用户自定义的怪物只具备些简单行为,跟尾随在身后的吉祥物差不多。对于自定义的怪物,玩家能够选择怪物的类型,例如是Dragon还是Bird,并且为其选择颜色等)。Monster的设计如下:

凡是Monster都要实现IMonster的接口。DuckMonster和CakeMonster为游戏公司预设的怪物类,场景中每出现一只头种怪物,都需要用到new DuckMonster或new CakeMonster。通过下面的两个工厂之一来解耦其实例化的代码。

而blueEyesWhiteDragon和bedEyesBlackBird为用户定义的一种怪物(请注意!他们不是类,而是实例),场景中每出现一头这种怪物,都需要调一次blueEyesWhiteDragon.Clone()或bedEyesBlackBird.Clone()。

先说一下MonsterFactory1与MonsterFactory2。

MonsterFactory1的缺点:MonsterFactory1每当增加一种新怪物的时候,就要增加一个GetXXMonter方法,等于不断地对外开放接口,而且方法多起来难以管理。

或者说为DuckMonster和CakeMonster各自建一个Factory,好处是只需要一个Get方法。缺点自然是Factory太多,无法管理。
MonsterFactory2的缺点自然是每增加一种新怪物,就多一个if来根据type参数来取得实例,不符合面向对象思想的“对扩展开放,对修改关闭”的原则。

到了MonsterPrototypeManager,通过依赖注入(对于依赖注入不理解的可以看看我的另外两篇文章:理解Spring中的依赖注入以及利用Spring解耦VS的WebService),我们可以不用写任何初始化的代码,来完成实例的创建,并且注入到regMonsterList这个Dictionary类的实例中。想获得实例,只要把type传进去GetSpecificMonster,就能从regMonsterList中取得相应的实例,并返回Clone后的实例。

在游戏过程中,高级玩家创建了一种新的怪物。由于这种怪物是一个实例,而不是一个类,所以还可以动态添加到regMonsterList当中,需要的时候可以拿出来Clone一下,来创建新实例。而MonsterFactory们就只能在编译时期确定好具体定义好的怪物“类”,灵活性比Prototype模式的MonsterPrototypeManager要差。

【编辑推荐】

  1. JavaScript设计模式之抽象工厂及工厂方法模式
  2. C#设计模式之抽象工厂(abstract factory)模式示例源代码
  3. C#抽象工厂模式的几种实现方法及比较
  4. SketchFlow:第一款真正意义上的原型设计工具
  5. Expression Blend 3新工具:用SketchFlow来设计原型
责任编辑:彭凡 来源: cnblogs
相关推荐

2024-03-06 13:19:19

工厂模式Python函数

2021-09-29 13:53:17

抽象工厂模式

2020-10-19 09:28:00

抽象工厂模式

2020-09-14 17:26:48

抽象工厂模式

2021-03-06 22:50:58

设计模式抽象

2009-01-15 10:55:29

JavaScript设计模式抽象工厂

2021-07-06 08:59:18

抽象工厂模式

2011-06-28 10:55:20

C#接口抽象类

2011-07-28 09:50:58

设计模式

2023-08-07 08:04:05

动态抽象工厂模式

2011-07-21 14:33:02

设计模式

2022-05-26 09:20:01

JavaScript原型原型链

2020-12-17 09:38:16

设计模式参数

2009-08-10 10:04:25

C#抽象类C#接口

2009-04-29 09:05:59

Lambda抽象代表.NET

2024-09-14 08:24:44

设计模式抽象工厂模式JDK

2017-05-05 10:31:35

JavaScriptprototype__proto__

2012-12-21 09:48:06

JavaJavaSE异常

2012-12-21 10:15:35

2012-02-14 09:43:08

点赞
收藏

51CTO技术栈公众号