【问题标题】:Bolting on abstract behavior dependent upon the same base?依赖于相同基础的抽象行为?
【发布时间】:2012-12-22 00:25:20
【问题描述】:

我希望有人能够帮助我解决我正在处理的设计问题。它专门针对游戏开发领域,但我认为这确实是一个更广泛的问题,可能已经以一种公认的方式解决了。我正在使用 Python。

我有一个 GameObject 类,它保存对象的位置(和其他一般状态属性)和对我的 Engine 对象的引用,该对象保存有关整个游戏世界的信息。 GameObjects 可以进一步分类:它们可以是 VisibleGameObjects、PhysicalGameObjects(可碰撞)或两者,具体形式。例如,我可以有一个不可见的边界,它是物理的,但没有可见的表示。

VisibleGameObjects 实现了一个处理绘图功能的 draw() 方法,并通过其父级的 Engine 引用委派此功能。 PhysicalGameObjects 具有边界框,并定义处理碰撞的逻辑,还需要访问 GameObject 属性(加速度、速度等)

问题是,当我想定义一个需要继承 VisibleGameObject 和 PhysicalGameObject(它们都共享一个父 GameObject)行为的具体对象时会发生什么?据我了解,这种循环继承是个大坏主意。

我如何重构它以将特定行为基本上固定到依赖于父抽象类状态的具体子类(可绘制、可碰撞)?

编辑:我的一个想法是将它们作为组件分配给 GameObjects 的具体实例,支持 has-a 关系而不是 is-a 关系。然而,即使这样看起来也不那么干净。尝试通过在“组件”列表中搜索可碰撞组件来检查对象是否可碰撞似乎也不是很好。

【问题讨论】:

  • 初读 - 听起来 Physical 和 Visible 应该是对象的属性,而不是单独的类
  • @JonClements 我认为这里的问题是他想公开不同的类函数。我认为正确的术语是 trait
  • @goncalopp 很可能——但我觉得我现在已经筋疲力尽了——在节日期间之前在电脑上开/关了将近 20 个小时整理东西——我想我现在要退休了!

标签: python oop game-engine object-oriented-analysis


【解决方案1】:

您似乎在寻找trait

不幸的是,python 本身不支持特征,尽管有 multiple modules 尝试实现该模型。

我的建议(除非您想依赖上述模块)是编写抽象类来公开您想要的行为,但不继承主类 - 将其留给第三个类,该类继承main 和行为类。

举个例子可能就不那么容易混淆了: 创建一个Visible 抽象类,它 继承自GameObject,并公开所有预期的行为/功能(好像 它继承自GameObject)。然后,让VisibleGameObject 继承自GameObjectVisible

显然,您只能设法在像 python 这样的动态语言上编写 Visible - 否则编译器会抱怨它无法访问不存在的字段。

【讨论】:

  • 很有趣,那么如何在 C++ 中实现这样的东西呢?看起来我的核心设计可能已经关闭,我应该重新考虑我的代理对象的行为..
  • @Drism 我自己从来没有用 C++ 做过,但是templates seem sufficient for the job。当您处理此类问题时,这是一种非常常见的模式。我不认为有办法完全避免它,但特征(在像 scala 这样的语言中是原生的)是一个非常好的解决方案,恕我直言
猜你喜欢
  • 2020-01-23
  • 2018-01-26
  • 1970-01-01
  • 2012-03-28
  • 2015-04-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多