首次提交代码十六年后,SQLite 已成为世界上部署最广泛的数据库引擎。这样的开源项目是学习如何让代码易于理解和维护的绝佳资源。
让我们从下面这段代码片段开始,来了解 SQLite 代码库的一些事实:

关于这个函数,有以下几点观察:
- 函数声明为 static。
- 函数返回错误码。
- 函数只有少量参数。
- 函数尽早退出。
- 使用断言检查某些条件。
- 未使用全局变量。
- 变量名易于理解。
- 方法很短。
- 函数体中没有多余的注释。
- 函数体缩进良好。
浏览 SQLite 源代码时,我们可以看到实现的一致性。同样的最佳实践规则应用于每一个函数。
以下是可以从 SQLite 代码库中学到的一些最佳实践:
使用结构体存储数据模型
在 C 编程中,函数使用变量来完成处理。这些变量可以是:
- 静态变量。
- 全局变量。
- 局部变量
- 结构体中的变量。
每个项目都有自己的数据模型,可能被许多源文件使用。使用全局变量是一种选择,但不是好的选择;将数据分组到结构体中通常更为可取。
让我们使用 CQLinq 和CppDepend搜索代码中定义的结构体:

许多结构体被用来定义数据模型。
让函数短小精悍
以下是Linux 编码风格网页上关于函数长度的建议:
Functions should be short and sweet, and do just one thing. They should
fit on one or two screenfuls of text (the ISO/ANSI screen size is 80x24,
as we all know), and do one thing and do that well.
The maximum length of a function is inversely proportional to the
complexity and indentation level of that function. So, if you have a
conceptually simple function that is just one long (but simple)
case-statement, where you have to do lots of small things for a lot of
different cases, it's OK to have a longer function.让我们搜索代码行数少于 30 的函数。

超过 90% 的函数代码行数少于 30 行。
封装
封装是指隐藏实现内部的函数和数据。在 C 语言中,封装通过 static 关键字实现。这些实体被称为文件作用域的函数和变量。
让我们执行下面的 CQLinq 查询,搜索所有静态函数。

我们可以看到,许多函数被声明为 static。
函数参数数量
参数个数 NbParameters > 8 的函数可能调用起来很痛苦,还可能降低性能。另一种方案是提供一个专门用于传递参数的结构体。

只有少数函数的参数超过 8 个。
局部变量数量
局部变量数 NbVariables 大于 8 的函数可能难以理解和维护。NbVariables 大于 15 的函数则极其复杂,应该拆分为更小的函数(除非它们是由工具自动生成的)。

只有少数函数的局部变量超过 15 个。
避免定义复杂的函数
有许多度量可以检测复杂函数;代码行数(NBLinesOfCode)、参数个数和局部变量个数是其中最基本的。
还有其他一些检测复杂函数的有趣度量:
- 圈复杂度是一个流行的过程式软件度量,其结果等于一个过程中可能发生的决策数量。
- 嵌套深度(Nesting Depth)是针对函数定义的度量,表示函数体中嵌套作用域的最大深度。
- 最大嵌套循环(Max Nested Loop)是函数中循环嵌套的最大层数。
这些度量可容忍的最大值主要取决于团队的选择,因为没有标准值。
让我们搜索可能需要重构的函数:

可以称得上复杂的函数非常少。
保持 const 正确性
C 语言提供了const关键字,用于表示对象不可更改,以及函数不会修改其参数。在所有恰当的地方使用 const 被称为"const 正确性"。刚开始会很难,但使用 const 确实能让您的编码风格更加严谨。
让我们搜索至少拥有一个 const 参数的函数:

函数耦合
调用许多其他函数的函数可能难以理解和维护。建议您尽量减少函数的扇出耦合(efferent coupling)。
在 SQLite 中,扇出耦合很高的函数非常少:

尽可能让函数尽早退出
函数尽早退出——尤其是通过函数顶部的守卫子句——是推荐的做法,因为它们能简化函数后续部分的逻辑。
在 SQLite 源代码中,这一最佳实践几乎应用于所有函数。
结论
研究知名的开源项目始终是提升编程技能的好方法。您无需下载和构建项目——只需在 GitHub 上浏览代码即可。
