博客 阅读时间 4 分钟

与 C++ 框架紧耦合的隐性成本

分享本文
The Hidden Cost of Tight Coupling to a C++ Framework.

市面上有许多 C++ 库和框架,使用它们可以加快项目的开发。在本文中,我们将探讨 C++ 应用程序高度依赖外部框架的弊端。但首先,库和框架之间有什么区别?为什么与框架的紧耦合可能比与库的紧耦合带来更多弊端?

下面是这篇文章对两者的一个有趣比较:

The key difference between a library and a framework is "Inversion of Control". When you call a method from a library, you are in control. But with a framework, the control is inverted: the framework calls you.

框架也可以这样定义:

It defines a skeleton where the application defines its own features to fill out the skeleton. In this way, your code will be called by the framework when appropriately. The benefit is that developers do not need to worry about if a design is good or not, but just about implementing domain specific functions.

总而言之,框架比库更具侵入性,它可能影响您应用程序的架构和设计。

例如,Qt 和 MFC 是两个知名的 C++ 框架;下面是它们各自网站上的定义:

Qt:

Qt is a cross-platform development 框架 enabling your team to deploy a single codebase providing common APIs across all supported platforms.

MFC 则是:

Your work with the Microsoft Foundation Class (MFC) Library 框架 is based largely on a few major classes and several Visual C++ tools. Some classes encapsulate a large portion of the Win32 application programming interface (API). Other classes encapsulate application concepts such as documents, views, and the application itself. Still others encapsulate OLE features and ODBC and DAO data-access functionality.

框架的侵入性更强;如果应用程序与它高度耦合,项目的几乎所有干系人都会受到影响。

招聘者:如果项目与某个外部框架高度耦合,几乎每位开发者都必须掌握这个框架,这让为项目招聘新开发者变得更加困难。确实,我们必须寻找已经具备所用框架经验的 C++ 开发者。

架构师和设计师:当项目与外部框架高度耦合时,我们会失去灵活性,项目的任何演进、迁移或改造都会变得更加复杂。

开发者:每个框架都有自身的复杂性;当它与项目紧密耦合时,每位开发者都需要掌握它。这给项目增加了复杂性,并可能显著影响开发时间和质量。

测试人员:当代码与框架紧密耦合时,要隔离并测试我们自己的代码非常困难。有时,测试人员需要做一些额外的工作才能测试应用程序。

使用外部框架可以加快项目的开发。然而,我们必须谨慎使用,尽量避免不必要的耦合。

让我们分析一些开源 C++ 项目,看看开发者要加入它们的开发团队需要具备哪些技能。

案例一:Emule 项目(http://www.emule-project.net)

用 CppDepend 分析 eMule 项目后,我们发现它主要使用 MFC 框架和 Windows API。

让我们看看该项目是否与 MFC 高度耦合;为此,我们可以让 CppDepend 找出哪些方法使用了 MFC。下面是树状图中的结果:

我们发现,几乎所有方法都使用了 MFC 框架,这使得 eMule 代码库与它高度耦合。

我们还可以搜索使用最多的 MFC 类:

MFC 贯穿整个项目:它使用了 GUI、Internet、Archive 和 Container 等类。

这种高度耦合有两个主要弊端:

  • 我们无法轻松地在其他项目中复用 eMule 的算法;如果想复用它们,也必须使用 MFC 库。
  • 任何想加入 eMule 项目的开发者都必须掌握 MFC 库。

案例二:OpenSTA 项目(http://sourceforge.net/projects/opensta/)

OpenSTA 被划分为多个项目;下面是它的部分项目依赖关系:

把一个项目划分为多个模块可以带来很大的好处:隔离功能使其更容易在其他项目中复用,并降低项目的复杂性。

哪些项目使用了 MFC?

我们发现,并非所有项目都使用 MFC 框架,而且最大的几个项目都没有使用它。

使用了哪些 MFC 类?

OpenSTA 主要使用 OLE 类。

即使不是 MFC 框架专家的 C++ 开发者,也可以加入 OpenSTA 团队,因为许多模块并不直接使用 MFC。

小结

隔离对外部框架的使用,对项目的所有干系人都大有好处;尽量保持简单,避免任何不必要的耦合,尤其是与业务层的耦合。

分享本文