面条式代码,是软件工程中反面模式的一种,也就是源代码的控制流程复杂,混乱难以理解,见到来说,就是屎一样的代码。

最小化变量的作用域,是避免产生面条式代码的一种有效方式。

作用域最小化是一种构建代码的方式,操作起来很容易

  • 声明具有最小作用域的变量
  • 用具有最小作用域的数据来分配变量

事实上,是代码的结构,定一了变量的可见性。

背景

一个程序是由一些单一或者组合的语句构成,例如赋值操作、条件判断、循环等。

通常来说,如果有两个代码块 A 和 B

  • 如果 A 包含 B,那么 A 就是 B 的外部代码块
  • 如果 B 被 A 所包含,那么 B 就是 A 的内部代码块

代码的缩进级别,是由嵌套级别数量决定的,直接的内部块会比其外部块多一个级别。

我们假设定义全局作用域,也就是没有外部块的代码,缩进级别为0,而全局变量,就是那些在全局范围内定义的变量。

变量可见规则

一个变量的可见性,由下面规则决定

  • 从该变量的声明语句开始
  • 结束于变量声明块的末尾
  • 并且在开始与结束中间的嵌套块中也是可见的

反过来说,如果一个变量是不可见的,那么

  • 在变量声明前
  • 在变量声明块结束后

建议

  • R1. 尽量不要使用全局变量
  • R2. 声明单一用途的变量
  • R3. 在接近变量用途的地方声明变量
  • R4. 保持小的代码块
  • R5. 使用靠近其声明的变量
  • R6. 使用不超过2层的嵌套

R1. 尽量不要使用全局变量

全局变量会使代码变得难以阅读和理解,难以维护和测试。

全局变量的使用,增加了出现问题的概率,并且不容易被发现。

程序中可能错误地分配变量的语句越少越好。

总之,全局变量的使用往往代表着技术债务,必须尽快重构以避免后期的不可维护。

R2. 声明单一用途的变量

为单一的特定目的声明和使用变量,以便将其作用域限制作到最小。

一个变量的目的性越多,意味着可访问此变量的代码块越多。

而变量可见的语句数量越多,可能错误地赋值变量的语句就越多。

可能错误地赋值变量的语句越多,那么发现和修复潜在错误就越困难。

R3. 在接近变量用途的地方声明变量

尽可能地在靠近将使用这些变量的语句和代码块的地方声明变量。

与 R2 严格相关。

R4. 保持代码块尽可能地小

单一的代码块,尽量只做单一的事情,保持代码块尽可能的小。否则一些变量很可能会被多个代码块访问,使可维护性变得困难。

假设有三个代码块 A B C,他们拥有相同的缩进程度。

假设我们需要声明一个变量 w,由 A 使用和修改,而只由 B 和 C 读取。

在代码块 A 之前声明 w 是不可避免的,否则 B 和 C 无法读取。但是这样使得 B 和 C 也可以对 w 进行赋值操作,但是我们希望 B 和 C 只能读取 w。

为了避免这种情况,只需要将 B 和 C 分成两个不同的函数,而 w 作为参数之一即可。

总结:让代码块成为单任务,将子任务移到独立的函数中。

R5. 使用靠近其声明的变量

一般来讲,一个变量的声明和使用之间,最大嵌套层数应该是两层。(尽可能)

R6. 使用不超过2层的嵌套

尽可能地减少代码的嵌套深度。尽可能地保持最多两层代码块的嵌套。

当一个函数的嵌套层数超过两个时,就需要考虑将子代码块移到单独的函数中。

特殊情况除外。