博客 阅读时间 6 分钟

深入 Macchina SDK 源代码:整洁的设计与实现

分享本文
A Look Inside the Macchina SDK Source Code: Clean Design and Implementation.

在 C++ 中,有许多库可以帮助您实现 IoT 应用,但大多数都是底层的。如果需要一个高层 SDK,Macchina.io是一个绝佳选择,尤其是当您在寻找一个能简化 IoT 应用开发的健壮框架时。

Macchina 不仅是 IoT 应用的强大解决方案,也是一个设计和实现都很出色的项目,让 SDK 用户能轻松理解和定制其行为。

让我们用 CppDepend 来看看 Macchina 的源代码,探索其设计和实现的一些方面。

整洁的设计

在设计一个具有良好文件夹结构的 C++ 项目时,重要的是考虑模块化可维护性可扩展性。按文件夹组织代码可以实现关注点分离,让导航、修改和扩展更容易。

从下面的 DSM 可以看出,Macchina SDK 拥有组织良好的文件夹结构:

基于 POCO 库的技术层被隔离在 platform 文件夹中。POCO C++ 库是强大的跨平台开源 C++ 库,用于构建运行在桌面、服务器、移动端、IoT 和嵌入式系统上的网络和互联网应用。

以下是一些 POCO 库的依赖关系图。

让我们深入 Foundation 项目,探索其结构:

源代码中的命名空间服务于三个不同的目的:

1- 模块化应用

现代 C++ 库广泛使用命名空间来模块化其代码库,并采用“按特性划分命名空间”的方法。这种方法用命名空间来反映特性集。

2- 匿名命名空间

匿名命名空间避免了使用全局静态变量的需要。您创建的匿名命名空间只能在定义它的文件中访问。

3- 按约定隐藏细节

在 C++ 中,没有办法对库用户隐藏公共类型(在 C# 中,“internal”关键字用于此目的)。因此,通过约定来表明某些类型不应被直接使用就很有用。

现代 C++ 中一个常见的惯用法(由 Boost 库的开发者开创)是将属于模块实现部分的符号(即不属于公共 API 的符号)分离出来。

Poco.Details 和 Poco.Dynamic.Impl 命名空间就是用来按约定隐藏实现细节的。

松耦合带来更大的灵活性

松耦合是可取的,因为应用某一区域的变更只需要系统其他部分做更少的改动。从长远看,这可以节省大量时间、精力和成本。

松耦合可以通过使用抽象类或泛型类型和方法来实现。

Macchina 源代码包含 300 多个抽象类:

例如,客户端认证器类是一个抽象类,允许多种实现,为用户认证功能提供了灵活性。

高内聚

单一职责原则指出,一个类不应有多于一个变更理由。这样的类被称为内聚的。高 LCOM 值通常指向内聚性差的类。

LCOM = 1 — (sum(MF)/M*F)
LCOM HS = (M — sum(MF)/F)(M-1)

其中:

  • M 是类中方法的数量(静态和实例方法都计入,还包括构造函数、属性的 getter/setter、事件的 add/remove 方法)。
  • F 是类中实例字段的数量。
  • MF 是类中访问某个特定实例字段的方法数量。
  • Sum(MF) 是类的所有实例字段上 MF 的总和。

这些公式背后的基本思想可以表述为:如果一个类的所有方法都使用其所有实例字段,则该类是完全内聚的,这意味着 sum(MF)=M*F,此时 LCOM = 0,LCOM HS 也为 0。

LCOM HS 值大于 1 应被视为警报。

整洁的实现

代码库中的大型类型很少

大型类型的开发和维护可能极其复杂。这样的类可能控制系统中太多其他类,增长到超出合理限度,变成“无所不能的类”。

在 Macchina SDK 源代码中,只有极少数类型特别大。

方法短小易懂

许多指标可用于识别复杂函数。代码行数(NBLinesOfCode)、参数数量和局部变量数量是其中基本的几个。

还有其他一些检测复杂函数的有趣指标:

  • 圈复杂度是一个流行的过程式软件指标,反映过程中的决策路径数量。
  • 嵌套深度是方法级指标,表示方法体内嵌套作用域的最大深度。
  • 最大嵌套循环表示函数中循环嵌套的最大层级。

这些指标可接受的最大值取决于团队的选择;没有通用的标准值。

在 Macchina SDK 源代码中,只有少数方法可以被认为是复杂的。

代码是可维护的

可维护性指数是一种软件指标,用于衡量代码库随时间推移的维护难易程度。它基于代码复杂度、规模和可读性等因素提供可量化的评分,帮助开发者评估代码质量。

让我们用 CppDepend 树状图来考察 Macchina SDK 方法的可维护性:

指标视图中,代码库通过树状图呈现。树状图是一种用嵌套矩形显示树形结构数据的方法。CppDepend 树状图使用的树结构是常见的代码层级:

  • C/C++ 项目包含命名空间,
  • 命名空间包含类型,
  • 类型包含方法和字段。

树状图的大小选项决定矩形的大小,默认与代码行数成正比;代码指标可以通过给代码元素矩形的着色来表示;在我们的例子中,颜色代表可维护性。

可以看到,只有少数方法显示为红色,而且其中大多数是测试方法。

结语

Macchina 以简化 IoT 应用开发而闻名。它的实现整洁、易懂、可定制,是 IoT 应用的绝佳选择。

分享本文