我有一些非常复杂的虚拟对象层次结构,它将3D Engine中的所有元素表示为抽象类(接口)。
例如,我有Renderable
哪个父级是Sizeable
(使用getSize()
方法)。 Sizeable
继承自Positionable
(getPosition()
)等。
该结构很好且逻辑正确(例如3D模型为Renderable
,用于蒙皮的骨骼骨骼为Sizeable
,而相机仅为Positionable
)。
还有一个“超级班”,Engine3D
。
我的目标是:
我必须为“图形事物”(模块)编写“实现”。它将是DirectX“实现”。 目标:使用我的“实现”的程序员可以切换到其他快速而简单的程序(他使用的实现对他来说几乎是透明的)。
我想保持这种方式:
//choosing module "implementation" ("implementation" mentioned here only)
Engine3D * engine = new MyEngine3D();
Renderable * model = engine->createModel(...);
//line above will return MyRenderable class in fact,
//but user (programmer) will treat it as Renderable
为什么我要创建Renderable
和其他所有版本的“自有”版本?因为他们将共享一些“实现”特定数据(DirectX结构的指针等)。
我的问题是:
但是这样,我会创建一个“镜像” - 原始模块的对象层次结构的副本,每个类名前面都有My
。此外,MyRenderable
必须继承Renderable
(超广render()
)和MySizeable
(以获取DirectX矩阵等)。
这涉及虚拟继承,并且确实使结构复杂化。
我主要讲的是避免虚拟多重继承(我认为只是多继承很好)。
答案 0 :(得分:2)
您绝对应该避免对象层次结构和渲染实现的强耦合。我的建议是将所有DirectX特定代码移动到对象层次结构之外的类,例如IRenderer
接口和DirectXRenderer
实现。向IRenderer
添加一个引用或指针到所有必须绘制内容的类(Renderable
等)。所有对象类必须使用您自己的矩阵实现等,以使它们独立于实际渲染后端的数据结构。