将C ++应用程序划分为库

时间:2009-06-12 17:30:41

标签: c++

我的C ++项目越来越大。我们现在也开始使用cmake进行构建。我想将应用程序分成库,以便它们可以链接进行测试,准备应用程序包等。现在我将我的代码分成如下库:

  • GUI
  • 实用程序(核心和其他组件使用它们)
  • io(使用核心类的打印函数进行xml解析/输出)
  • 测试(单元测试)
  • 模拟器(测试核心)

另一种方法是根据目录结构进行划分 - 每个目录有一个库。但是从我过去的经验来看,它导致了太多的库,然后在链接过程中变得难以处理库依赖。

这方面是否有最佳做法?

4 个答案:

答案 0 :(得分:5)

用一张纸坐下来决定你的图书馆架构。

图书馆应设计为一组级别。

  • A级(基础)上的一个库只应该在系统库上有依赖关系,并且只有它必须在A级的库上才有。
  • B级的库可以依赖于A级和系统库的库,只有它必须位于B级的库上。

每个图书馆应代表其特定级别的完整工作。较低级别的事情通常会有较小的工作,但很多。更高级别的库应该重新发送完整的任务。即没有用于windows对象的lib和用于事件的lib。在这个级别,这里的工作是手动与窗口的所有交互(这包括它与事件的交互方式)。

您似乎已经确定了一些合理的功能组。唯一一个看起来有点可疑的是io。如果你真的有一些通用的IO例程,可以提供真正的功能。但是,如果只是将IO分组为一堆不同的对象,那么我会废弃它(这完全取决于使用情况)。

所以下一步是确定它们之间的关系。

至于使用目录结构。通常,一个目录中的所有内容都将出现在同一个库中,但这并不排除其他目录的可用性。我会避免将一半的类放在libA的目录中,另一半的类放在libB等中。

答案 1 :(得分:2)

您应该阅读John Lakos撰写的大规模C ++软件设计。

在开始工作之前,您可能无法阅读,但您应将此书放在列表中。

否则马丁约克的建议是合理的。

还有一件事,我建议选择像doxygen这样的工具,它可以为你提供代码库的依赖关系图。如果你不想做这种类型的重组,你应该摆脱你的库之间的循环依赖。 Lakos描述了很多削减依赖关系的方法 - 有些是显而易见的,有些则不那么明显。

答案 2 :(得分:1)

我喜欢从只有单向箭头的包图开始。

http://www.agilemodeling.com/style/packageDiagram.htm

你的清单看起来是一个好的开始。

答案 3 :(得分:1)

似乎合理。

我会查询你的unit_tests库应该做什么。 给定构建libA,libB,libC的“项目”集合......我希望看到一些匹配的项目testA testB testC(它们是否构建库或可执行文件取决于构建的测试是独立运行还是加载到某个测试运行器中)

我也对“实用程序”库略有警惕。从长远来看,这些似乎具有令人惊讶的引起疼痛和痛苦的能力。例如,您的IO库可能没有其他依赖项而不是实用程序库。有一天,您希望在另一个平台上的另一个项目中重用IO库。唯一的问题是,您现在还必须移植所有实用程序库(其中90%的IO不使用),或者解开IO实际依赖的10%。有时,以某些代码重复为代价,让库更加无依赖性更好。