抽象工厂与抽象参数?

dee*_*146 8 c++ factory-pattern

我正在尝试用抽象工厂设计一个好的实体创建系统(根据http://www.dofactory.com/Patterns/PatternAbstract.aspx),但是当涉及到实例特定的参数时,我正在努力.

例如:我有两个抽象工厂,一个用于创建一个抛射物,另一个用于创建一个箱子

现在工厂可以是每种类型的一个实例,它从列表中传递一个抽象参数集(在基类中共享材料,大小等),类型特定参数将是射弹的速度和耐久性箱.

但是我正在努力的是,最后当我有这个抽象的工厂方法,我用字符串"BulletProjectile"和"WeakCrate"调用时,我需要提供特定于实例的参数,更重要的是它们是不同工厂的不同类型 - 对于弹丸,他们会有位置和速度,箱子只有位置.更糟糕的情况是用户或玩家正在创建板条箱或类似对象,并且能够定义其尺寸.我该怎么处理?

Mer*_*ham 5

几个选项:

重新考虑你的用法

如果将工厂用户与生成确切类型的方式分开,则抽象工厂很有用.抽象工厂对它产生的东西没有任何限制,只是它是抽象的.它可以返回非抽象类型,或者不在继承层次结构基础上的抽象类型.

如果使用工厂的代码已经可以获得不同的数据集来调用工厂,那么使用工厂的代码已经知道了它的类型.

以下是一些可以考虑的选项:

  • 提供多个抽象工厂类型,Create每个类型都有一个方法,例如a GrenadeFactory和aBulletFactory
  • 在单个抽象工厂类型上提供多种方法,例如CreateBulletCreateGrenade
  • 停止使用抽象工厂.如果你真的不需要抽象构造,只需要抽象类型,这是一个很好的选择.

请记住,您仍然可以将派生类型(Bullet)传递给采用基类型(例如,EntityProjectile)的方法.

双重派遣

如果您真的将抽象工厂与抽象参数结合起来,那么您可能需要查看双重调度或访问者模式.这里的关键是您尝试将两种不同的虚拟方法相互组合,并根据这两种派生类型获得独特的行为组合.

这将要求您为参数创建基类型和派生类型,因此您无法传递简单类型(如int,string等),而无需创建从基Parameters类型派生的自定义参数结构.

它还需要大量额外的代码来实现访问者模式.

RTTI

您可以使用C++运行时类型信息功能.

使用时dynamic_cast,可以将基类型转换为派生类型.您可以在工厂实现中执行此操作,以将基本参数类型转换为特定参数类型.

与double-dispatch一样,这也需要您为参数创建类型层次结构,但需要较少的代码将它们拼接在一起(不需要访问者模式).

但是,此选项会将工厂实现紧密耦合到参数结构实现.

物业包

您还可以使用string- > some type字典(例如string- > boost::any).这被称为财产袋.但是,它失去了很多编译时类型的安全性,因为你基本上是按字符串值查找所有内容.我真的不推荐它.