【发布时间】:2014-10-20 13:17:02
【问题描述】:
如果我想使用 DIP 开发一个假设的模块化 C++ 项目。由于模块化,我选择在一个库A 中完全实现一项特定功能。另一个库B(或两个,或三个...)正在使用此功能(例如日志记录机制):
class ILogger
{
virtual void log(const std::string& s) = 0;
};
我应该把这个接口物理放在哪里? 一些博主似乎建议,因为接口属于它的用户(因为 DIP)you shall put the interface on the user side(或here)。这也将提高可测试性,因为您不需要将任何实现链接到测试。
这意味着库 A 本身将无法编译,因为它缺少接口。这也意味着,如果库 C 也将使用日志记录工具,它还将引入一个接口ILogger,这将破坏ODR?!这可以通过引入仅包含接口的额外包层库 D 来解决。但主要问题仍然存在:
接口放在哪里?我阅读了关于 DIP 的原始paper,但我不同意这种解释,即我不应该将接口放入库中。我有一种感觉,这篇论文旨在作为如何思考开发的指南(因为“用户定义的是接口而不是实现者”)。它是否正确?如何使用依赖倒置原则?
【问题讨论】:
-
将接口放在单独的库中怎么样?然后,您可以从 A 和 B 中包含该库。最后,建议用于 DIP ...
-
对于大多数用例来说,这可能被夸大了。对我来说最有问题的情况是:如果您将接口与用户一起打包,并将实现打包在另一个包中,那么它将从带有实现的包添加到带有用户和接口的包的构建依赖项。恕我直言,仅仅为了获得一点可测试性优势,这是不合理的。
标签: c++ deployment dependencies modularity dependency-inversion