根据广泛传播的建议,我应该注意尽可能保持我的大型软件项目的模块化.当然有各种方法可以实现这一点,但我认为没有办法使用更多或更少的接口类.
以C中的2D游戏引擎为例.
现在,人们当然可以通过使用几乎所有东西的接口来实现一个非常模块化的系统:从渲染器(界面渲染器类 – > Dummy,OpenGL,DirectX,SDL等),通过音频到输入管理.
然后,可以选择广泛使用消息传递系统.但从逻辑上讲,这些产品的性能价格也很高.
我该如何构建这样的工作引擎?
我不想在性能方面(实体,粒子等的最大可行数量)降低我的引擎的限制,只是为了让一个完美的模块化系统在后台工作.这很重要,因为我还想针对CPU功耗和内存有限的移动平台.
例如,具有渲染器类的接口将涉及用于时间关键绘制操作的虚函数调用.仅这一点就会使发动机减速很多.
这是我的主要问题:
>我应该在哪里通过模块化编程在一致性和性能之间划清界线?
>有哪些方法可以使项目保持模块化,同时保持良好的性能以适应时间紧迫的操作?
解决方法:
有许多方法可以在不使用单个“接口”类的情况下保持代码模块化.
>您已经提到了消息传递
>然后有一些简单的旧回调.如果对象需要能够在系统中的其他位置触发某个事件,请为其提供一个可以调用以触发该事件的回调函数.然后,它不需要了解您的其他架构
>并且使用模板和静态多态,您可以实现与接口类相同的大多数目标 – 但是性能开销为零. (例如,模拟游戏引擎,以便在编译时可以选择基于Direct3D或OpenGL的渲染器)
此外,模块化是棘手的,并不是通过隐藏接口后面的所有东西而得到的.对于它是模块化的,无论该接口实现什么都应该是可替换的.您必须有一个策略来将一个实现替换为另一个实现.并且必须能够创建多个不同的实现.
如果你只是盲目地隐藏接口后面的所有内容,那么你的代码根本就不是模块化的.替换任何实现任何东西将是一个巨大的痛苦,因为你需要挖掘无数的接口层来做到这一点.您必须遍历代码中的数百个位置,并确保选择并实例化并传递正确的实现.并且您的界面将如此通用,以至于它们无法表达您需要的功能,或者特定于无法实现其他实现.
如果你想要一个俗气的比喻,砖块是模块化的.砖可以很容易地取出并用另一块砖代替.但是你也可以将它们磨成细小的烤粘土颗粒.这是模块化的吗?你当然创造了更多,更小的“模块”.但唯一的影响是更换任何给定的组件要困难得多.我不能再拿起一块有形的砖块扔掉,把它换成砖块大小的东西.相反,我必须经历数千个小颗粒,为每个小颗粒寻找合适的替代品.而且由于被更换的部件不再被更大结构中的几块砖包围,但是有数十或数十万个颗粒,现在还有一些荒谬的其他“模块”受到影响,因为我换掉了他们与之接口的邻居. .
将所有东西磨成更细小的位并不会使任何更加模块化.它只是从您的应用程序中删除所有结构.编写模块化软件的方法是实际思考和确定哪些组件在逻辑上是如此独立且不同,以至于可以在不影响应用程序其余部分的情况下替换它们.然后编写应用程序和组件,以保持这种隔离.