我只能处理最简单的情况,只有2个模块 A 和 B
A 依赖于 B ,因此我将 B 构建为库并包含 B 的标题文件在 A 中,在构建 A 时也链接到 B 库。
当 A 和 B 相互依赖时,这不起作用,当模块数量增加时更糟糕。
那么在c/c++
中进行模块化开发的一般方法是什么?
更新
很抱歉,似乎我的标题是无效的,重新定义的版本是:如何将模块划分为多个.h
和.cpp
文件(不是一个)?
答案 0 :(得分:5)
如果A和B是相互依赖的,则不能单独部署它们中的任何一个。因此,您实际上只有一个模块,而不是两个模块。 (您可以重构模块以将常用内容提取到第三个模块C中,从而使A和B都依赖于C而不是相互依赖。)
设计良好的项目不应包含循环模块依赖项。这可以保证模块之间始终存在合理的构建顺序。
如何将模块划分为多个.h和.cpp文件(不是一个)?
基本原理非常类似于模块级别:避免循环依赖和重复定义。 @Felix已经提到了这方面的基本工具:前向声明和包括警卫。我还可以通过@ kotlinski对Larman书籍的推荐来深入理解这个主题。
学习好的设计需要练习,所以如果你的第一种方法看起来不完美,不要放弃:-)在C ++中,一个特别的痛苦是在改变后过度重新编译。为了最大限度地减少这种情况,请努力确保您最依赖的事物(类,标题)是最不频繁更改的事物。即依赖于接口(抽象类),而不是具体的实现。
此外,努力在逻辑分区(类/组件)和物理分区(header / cpp文件)之间保持健康的关系。典型的方法是将每个类定义放入一个单独的头文件中,并将其实现(如果适用)放到单独的cpp文件中。但是,您可能更喜欢在单个标头中定义紧密耦合的类(组件),以强调它们的逻辑关系。
答案 1 :(得分:5)
一般来说,拥有两个相互依赖的模块是一种设计气味。你可以
1)将模块合并为一个新的C或
2)将一个共同的子集提取到I中,使得A和B依赖于I而不是彼此。
<强>更新强>
使用前向声明和#pragma once或#include / #ifndef protection:
答案 2 :(得分:4)
解决方案是确保您的模块形成有向无环图... I.e.如果A依赖于B,请确保B不依赖于A.它需要很多纪律,但从长远来看是值得的。
如果您对这些内容感兴趣,Large Scale C++ Software Design是一个很好的阅读。
答案 3 :(得分:0)
Design Patterns,例如Model–View–Controller - MVC。
模型 - 视图 - 控制器(MVC)是一种软件架构,1目前被认为是软件工程中使用的架构模式。该模式将“域逻辑”(用户的应用程序逻辑)与输入和表示(UI)隔离开来,允许对每个模块进行独立开发,测试和维护。