首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++和模块化:我应该在哪里划定界限呢?

C++和模块化:我应该在哪里划定界限呢?
EN

Stack Overflow用户
提问于 2011-06-26 17:49:39
回答 4查看 1.5K关注 0票数 3

根据广泛传播的建议,我应该注意保持我的大型软件项目尽可能模块化。当然,实现这个目标有很多种方法,但我认为没有办法或多或少地使用许多接口类

以C++中2D游戏引擎的开发为例。

现在,我们当然可以通过使用接口来实现一个非常模块化的系统:从渲染器( ->假人、OpenGL、DirectX、SDL等)到输入管理。

然后,可以选择广泛使用消息传递系统,例如。但从逻辑上讲,这再次带来了很高的性能代价。

我怎么能造出这样的工作引擎呢?

我不想降低我的引擎在性能方面的限制(实体、粒子等的最大可行数量),只是为了让一个完美的模块化系统在后台工作。这很重要,因为我也希望针对CPU能力和内存有限的移动平台。

例如,拥有呈现器类的接口将涉及对时间关键的绘图操作的虚拟函数调用。光是这一点就会使发动机减速相当大。

以下是我的主要问题:

我应该在哪里用模块化programming?

  • What在一致性和性能之间划出界限呢?有哪些方法可以保持项目模块化,同时在关键时间的操作中保持良好的性能呢?
EN

回答 4

Stack Overflow用户

发布于 2011-06-26 17:59:22

有许多方法可以保持代码模块化,而无需使用单个“接口”类。

  • ,您已经提到了传递
  • 的消息,然后是普通的旧回调。如果一个对象需要能够触发系统中其他地方的某个事件,那么就给它一个回调函数,它可以调用这个函数来触发该事件。它不需要了解您架构的其他部分--然后是
  • --使用模板和静态多态性,您可以实现与接口类相同的大多数目标--但性能开销为零。(例如,模板您的游戏引擎,以便在编译时可以选择基于Direct3D或OpenGL的渲染器)

此外,模块化是很棘手的,而不是仅仅通过隐藏接口后面的所有东西就可以得到的东西。为了使它是模块化的,接口实现的任何东西都应该是可替换的。您必须有一个用另一个实现替换一个实现的策略。而且必须能够创建多个不同的实现。

如果您只是盲目地将所有内容隐藏在接口后面,那么您的代码根本就不会是模块化的。替换任何实现都会带来巨大的痛苦,因为要做到这一点,需要挖掘无数层的接口。您必须遍历代码中的数百个地方,并确保选择、实例化和传递正确的实现。而且您的接口将是如此的通用,以至于它们无法表示您所需要的功能,或者如此具体,以至于无法进行其他实现。

如果你想要一个俗气的比喻,砖块是模块化的。一块砖可以很容易地拿出来,用另一块砖代替。但你也可以把它们磨成很小的烤粘土颗粒。这是更模块化吗?当然,您已经创建了更多、更小的“模块”。但唯一的效果是使替换任何给定组件的难度大得多。我不能再拿起一块有形的砖头,扔掉它,用砖头大小的东西来代替它。相反,我必须经历数千个小粒子,为每个粒子找到一个合适的替代品。因为被替换的组件不再被更大的结构中的几块砖块包围,而是有数万个或几十万个粒子,所以现在有很多其他的“模块”受到影响,因为我把他们的邻居交换出来了。

把所有东西磨成更细和更小的钻头并不能使任何东西变得更加模块化。它只是从应用程序中删除了所有的结构。编写模块化软件的方法是实际地思考和确定哪些组件在逻辑上是如此孤立和不同,以至于可以在不影响应用程序其余部分的情况下替换它们。然后编写应用程序和组件,以维护这种隔离。

票数 3
EN

Stack Overflow用户

发布于 2011-06-26 18:51:00

首先是原型,然后让界面边界出现。

先发制人的界面设计可以使编码成为一种拖动。

在编写代码之前尝试设计抽象障碍是很棘手的,因为您有两个风险。其一,您将不可避免地在错误的地方设置一些抽象障碍,当您开始编写工作代码(相对于接口代码)时,您会发现您的接口为您的问题服务很差,尽管用自然语言描述时听起来不错。另一个问题是,它使编码变得更加拖拉,因为您必须在头脑中处理两个问题,而不是一个:为一个尚未完全理解的问题编写工作代码,以及坚持一个可能会导致错误的界面。

界面边界来自工作代码。

当然,我并不是说接口不好,而是说如果不先编写工作代码,就很难正确设计。一旦您有了一个工作程序,很明显哪些部分应该是同一个虚拟函数的不同实例化,哪些函数需要共享资源(因此应该放在同一个类中)等等。

原型,然后只绘制您需要的界面边界。

因此,我同意@jdv-Jan de Vaan的建议,即首先要做的事情是写出最短的可读程序。(这与最短的程序不同。当然,即使在刚开始的时候,界面设计也是最少的。)我的补充是说界面设计是在那之后的。也就是说,一旦您有了尽可能简单的代码,就可以将其重构为接口,使其更短、更易读。如果您想要具有可移植性的接口,那么在您真正拥有两个或多个平台的代码之前,我不会启动它。然后,接口边界将以一种自然(和可测试)的方式出现,因为可以同时使用哪些功能,以及需要在接口后面隐藏多个实现。

票数 2
EN

Stack Overflow用户

发布于 2011-06-26 18:16:22

我不同意这个建议(或者你的解释)。“尽可能模块化”:这应该在哪里结束?您打算为3d向量编写虚拟接口吗?这样您就可以切换实现了吗?我不这么认为,但这将是“尽可能模块化”。

如果您正在销售游戏引擎,模块化可以帮助您降低构建时间,减少预期客户所需的头文件数量,以及切换特定问题域实现的能力(例如directx与opengl)。它还可以通过对代码进行分区来帮助您的代码可维护。但在这种情况下,不需要将模块与接口解耦。

我的建议是始终编写,这是工作的最短可读性程序。如果您可以编写20行代码,在本地解决某些问题,或者将函数分散到五个不同的类中,则后者将更加模块化,但结果通常不那么可靠、可读性差、可维护性差。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6485648

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档