Ruby&模块化 - 有没有干净的&简单的方法排除包括||扩展模块/ mixins从类?

时间:2011-12-13 21:51:49

标签: ruby module multiple-inheritance modularity mixins

Stackoverflowers!

我最近开始涉足Ruby,我有几个问题。首先是一些背景:我习惯于C ++和Java继承,并且总是不喜欢在很多与游戏相关的场景中继承如何工作(例如,roguelike)。主要是由于很难以良好的方式封装行为。例如,在Java中:(不是我以这种方式实现它,但这是我能在短时间内提出的最佳示例。)

Actor extends GameObject
Creature extends Actor

FlyingCreature extends Creature
Dragon extends FlyingCreature

Humanoid extends Creature

......到目前为止这么好,对吗?但是,如果我决定实施一个“Gargoyle”(有翼的人形)类怎么办?然后它将属于FlyingCreature和Humanoid - 所以我必须封装其中一个特征,然后重构它或其他东西。

理想的解决方案 - 个人 - 如果有一些有效的方法将独特的属性/功能提取到封装的对象中,然后让每个GameObject都是可以相互交互的不同模块化组件的组合。 (除了诸如Item:GameObject,Actor:GameObject,Tile:GameObject之类的可能性之外没有继承,即使那时)。

通过创建一个组件树,可以很容易地创建一个特定的GameObject(比如一个orc) - 粗略地像这样但更灵活:

          [Actor]
[Organic]/  |    \[Persona] // Name, etc..
            |          \
       [Humanoid]      [Intelligence] // AI or PlayerController
            |
       [Inventory] // [ArrayList of items...]
            |
       [Equipment] // [Hash of :slot -> Item]

但更重要的是:当我开始学习Ruby时,我了解了它的元编程能力,它是由于语言反射而产生的运行时自由,以及模块的扩展/包含功能。所以我认为,如果我将特定的特征划分为模块(并确保有仔细的命名策略等),那么我可以允许我的类根据上下文和事件包含行为。例如,假设我有一个名叫Bob O'Copp的矮人 - 他在一个黑暗的下水道地牢中探险时,他会骑着一只小小的吸血鬼仔猪。因此,他陷入了一些使他变异的神奇化学水坑 - 给他可爱的仙女翅膀。但由于矮人通常不是鸟类,他的班级不具备飞行功能。但对于这个例子,它将是一个有效的特征。因此,我认为“bob.extend Flight”将是一个很好的解决方案。

但是如果其中一个特征是暂时的呢?让我们说鲍勃奥科普找到一个卷轴,在法术持续时间内召唤魔法翅膀......但是。经过大量的谷歌搜索后,我还没有找到任何关于如何在应用后撤回/取消扩展或排除mixins的好信息 - 如果实际上可行的话。因为这里有很多非常聪明且经验丰富的程序员,所以我想正式恳请你赐予你一些伟大的洞察力,强大的大胡子啊! : - )

所以...几个问题:

  • 我是否妄想想以这种方式使用mixins?
  • 我有没有想到的一些重大缺点?
  • 一旦应用,是否可以收回mixin?
  • 您是否有任何其他建议可以解决问题? (给我一些关键字形式的方向就足够了)

热切期待任何回复预期

非常感谢提前,

-Robocopulate

1 个答案:

答案 0 :(得分:5)

我是否因为想以这种方式使用mixins而妄想?
我不认为你是妄想症。临时混音听起来像是描述你的目标的巧妙方式。

我有没有想到的一些重大缺点?
经过一段时间的反思,这对我来说并不是那么明显,除了(见下一个问题)......

一旦应用,是否可以收回mixin? 不是未经修改的Ruby。添加unextend或类似内容的提议有很多,但尚未添加到官方语言中。

但是,有Remix库,可为您提供unextendtemp_include以及更多内容。如果您打算在Remix可用的地方运行,可以使用它。

您是否有其他建议可以更好地解决问题?
您可以随时滚动自己的继承系统。 :|例如,创建模块函数,接受要操作的实例(可能使用instance_eval来违反其封装并存储自定义数据),然后跟踪特定模块是否可用。