抽象工厂与抽象参数?

时间:2011-06-05 05:16:13

标签: c++ factory-pattern

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

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

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

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

1 个答案:

答案 0 :(得分:5)

几个选项:

重新考虑您的使用

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

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

以下是一些需要考虑的选项:

  • 提供多种抽象工厂类型,每种类型都有一个Create方法,例如GrenadeFactoryBulletFactory
  • 在单个抽象工厂类型上提供多种方法,例如CreateBulletCreateGrenade
  • 停止使用抽象工厂。如果您不需要抽象构造,并且只需要抽象类型,这是一个不错的选择。

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

双重发送

如果您真的已经将抽象工厂与抽象参数组合在一起,那么您可能希望研究双重调度或Visitor Pattern。关键在于您尝试将两种不同的虚拟方法相互组合,并根据这两种派生类型获得独特的行为组合。

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

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

<强> RTTI

您可以使用the C++ Run-Time Type Information feature

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

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

但是,此选项会将工厂实现与参数结构实现紧密结合。

物业袋

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