我在应用程序架构中有以下问题,并愿意解决它(对不起,很多文字)。
我正在构建一个游戏引擎原型,并且我有基本的抽象类AbstractRenderer
(我将使用 C++ 语法,但问题仍然很普遍)。
假设这个渲染器有一些派生的实现,比如说DirectxRenderer
and OpenglRenderer
。
现在,假设这些渲染器中只有一个(让我们坚持基于 DirectX)有一个名为“IDirect3D9Device* m_device;
显然此时一切都很好”的成员 -m_device
在内部使用DirectxRenderer
并且不应该在抽象AbstractRenderer
超类中公开。
我还添加了一些抽象的渲染接口,例如IRenderable
. 这仅意味着一种纯虚方法virtual void Render(AbstractRenderer* renderer) const = 0;
这就是一些问题开始的地方。假设我正在为某个场景建模,那么这个场景中可能会有一些几何对象。
我创建抽象超类AbstractGeometricalObject
和派生的基于 DirectX 的实现DirectxGeometricalObject
。第二个负责存储指向 DirectX 特定的顶点和索引缓冲区的指针。
现在 - 问题。
AbstractGeometricalObject
显然应该派生IRenderable
接口,因为它在逻辑上是可渲染的。
如果我派生出我DirectxGeometricalObject
的 from AbstractGeometricalObject
,第一个应该有virtual void Render(AbstractRenderer* renderer) const { ... }
方法,那Abstract...
东西会带来一些麻烦。
请参阅代码以获得更好的解释:
现在我的课程看起来如下:
class AbstractGeometricalObject : public IRenderable {
virtual void Render(AbstractRenderer* renderer) const { ... }
};
class DirectxGeometricalObject : public AbstractGeometricalObject {
virtual void Render(AbstractRenderer* renderer) const {
// I think it's ok to assume that in 99 / 100 cases the renderer
// would be a valid DirectxRenderer object
// Assume that rendering a DirectxGeometricalObject requires
// the renderer to be a DirectxRenderer, but not an AbstractRenderer
// (it could utilize some DX-specific settings, class members, etc
// This means that I would have to ***downcast*** here and this seems really
// bad to me, because it means that this architecture sucks
renderer = dynamic_cast<DirectxRenderer*>(renderer);
// Use the DirectX capabilities, that's can't be taken out
// to the AbstractRenderer superclass
renderer.DirectxSpecificFoo(...);
}
我知道我可能担心太多了,但是在如此简单的情况下,这种沮丧意味着如果我的应用程序增长,我可能会被迫做出很多沮丧。
当然,我想避免这种情况,所以请你在设计方面给我一些更好的建议/指出我的错误。
谢谢