保持模块独立,同时仍然互相使用

时间:2010-09-23 17:02:13

标签: c++ language-agnostic oop modularity

我的C ++应用程序的很大一部分使用类来描述数据模型,例如类似ClassType(实际上模仿普通C ++中的反射)。

我想在我的应用程序中添加一个新模块,它需要使用这些ClassType,但我不想在ClassType上引入新模块的依赖项。

到目前为止,我有以下备选方案:

  • 不使它独立并引入对ClassType的依赖,可能会在我的应用程序中创建更多“spaghetti”依赖项(这是我最不喜欢的解决方案)
  • 介绍一个新课程,例如IType,让我的模块只依赖于IType。然后ClassType应该从IType继承。
  • 使用字符串作为标识方法,并强制新模块的用户将ClassType转换为字符串,反之亦然。
  • 使用GUID(甚至简单整数)作为标识,还需要在GUID和ClassType之间进行转换

在解耦应用程序中的模块时,您应该尝试多远?

  • 只是介绍一个接口,让所有其他模块都依赖于接口? (如上面描述的IType)
  • 甚至通过使用其他标识如字符串或GUID来进一步解耦?

我担心通过将它解耦得太远,代码变得更不稳定并且更难以调试。我在Qt中看过一个这样的例子:信号和插槽使用字符串链接,如果你输入错误,功能不起作用,但它仍然可以编译。

您应该将模块分离多远?

3 个答案:

答案 0 :(得分:2)

99%的时间,如果您的设计基于反射,那么您在设计方面存在重大问题。

一般来说,像是

if (x is myclass)
elseif (x is anotherclass)
else

是一种糟糕的设计,因为它忽略了多态性。如果你这样做,那么x项就违反了Liskov替代原则。

另外,鉴于C ++已经有了RTTI,我不明白你为什么要重新发明轮子。这就是typeofdynamic_cast的用途。

答案 1 :(得分:1)

我会避开思考你的反思,只看一下依赖性的想法。

去耦合分离是合理的。耦合意味着,如果一件事发生变化,那么另一件事就必须所以你的NewCode正在使用ClassType,如果它的某些方面发生了变化,那么你肯定必须改变NewCode - 它不能完全解耦。您想要从以下哪个地方解耦?

  1. 语义,ClassType的作用。
  2. 界面,您如何称呼它。
  3. 实施,如何实施。
  4. 在我看来,前两个是合理的耦合。但肯定的是,实现更改不应该要求NewCode更改。所以代码接口。我们试图保持接口固定,我们倾向于扩展它们而不是改变它们,如果可能的话,保持它们是后向兼容的。有时我们使用名称/值对来尝试使接口可扩展,然后点击你提到的错误类型的错误。这是灵活性和“类型安全”之间的权衡。

答案 2 :(得分:0)

这是一个哲学问题;这取决于模块的类型和权衡。我认为我已经在不同时间亲自完成了所有这些操作,除了GUID类型映射,在我看来,它与字符串到类型映射没有任何优势,并且至少字符串是可读的。

我想说,鉴于预期的外部使用和代码组织,你需要查看特定模块需要什么级别的解耦,然后从那里开始。据我所知,你已经触及了所有概念方法,并且它们在特定情况下都是有用的。

无论如何,这是我的意见。