我正在尝试设计一个具有抽象工厂的好的实体创建系统(根据http://www.dofactory.com/Patterns/PatternAbstract.aspx),但是当涉及到特定于实例的参数时,我会遇到困难。
例如:我有两个抽象工厂,一个用于创建投射体,另一个用于创建板条箱
现在工厂可以是每种类型的一个实例,它从列表中传递一个抽象参数集(在基类中将共享材料,大小等),类型特定的参数将是弹丸的速度和板条箱的耐久性。
但我最终遇到的问题是,当我有了这个抽象的工厂方法,我用字符串"BulletProjectile“和"WeakCrate”这样的参数调用它时,我需要提供实例特定的参数,更重要的是,它们对于不同的工厂具有不同的类型-对于弹丸,它们将具有位置和速度,而crate将仅具有位置。更糟糕的情况是,用户或玩家正在创建一个板条箱或类似的对象,并且能够定义其尺寸。我该怎么处理呢?
发布于 2011-06-05 13:39:35
以下是几个选项:
重新思考你的用法
如果抽象工厂将工厂的用户与确切类型的生成方式分开,那么它就很有用。抽象工厂对它产生的内容没有任何限制,只是它是抽象的。它可以返回非抽象类型,也可以返回不在继承层次结构最底层的抽象类型。
如果使用工厂的代码已经可以获得不同的数据集来调用工厂,那么使用工厂的代码已经对从工厂中产生的类型有了一定的了解。
以下是一些需要考虑的选项:
Create方法,比如单个抽象工厂类型上的GrenadeFactory和BulletFactoryCreate和CreateBullet。如果您并不真正需要抽象构造,而只是需要抽象类型,那么这是一个很好的选择。请记住,您仍然可以将派生类型(Bullet)传递给接受基本类型(例如,Entity或Projectile)的方法。
双重派单
如果你真的一心想把抽象工厂和抽象参数结合起来,那么你可能想看看double dispatch,也就是Visitor Pattern。这里的关键是,您正在尝试将两个不同的虚拟方法相互组合,并基于这两个派生类型获得唯一的行为组合。
这将要求您为参数创建基本类型和派生类型,因此如果不创建从基本Parameters类型派生的自定义参数结构,则无法传递简单类型(如int、string等)。
它还需要大量额外的代码来实现访问者模式。
实时
您可以使用the C++ Run-Time Type Information feature。
使用dynamic_cast,可以将基类型强制转换为派生类型。您可以在工厂实现中执行此操作,以便将基本参数类型转换为特定的参数类型。
与双重分派一样,这也需要为参数创建一个类型层次结构,但需要更少的代码来将它们缝合在一起(不需要访问者模式)。
但是,此选项会将您的工厂实现与参数结构实现紧密耦合。
属性包
您还可以使用string -> some type字典(例如,string -> boost::any )。这被称为属性包。但是,它失去了大量的编译时类型安全性,因为您基本上是通过字符串值来查找所有内容。我并不真的推荐它。
https://stackoverflow.com/questions/6241146
复制相似问题