面条式代码,是软件工程中反面模式的一种,也就是源代码的控制流程复杂,混乱难以理解,见到来说,就是屎一样的代码。
最小化变量的作用域,是避免产生面条式代码的一种有效方式。
作用域最小化是一种构建代码的方式,操作起来很容易
- 声明具有最小作用域的变量
- 用具有最小作用域的数据来分配变量
事实上,是代码的结构,定一了变量的可见性。
背景
一个程序是由一些单一或者组合的语句构成,例如赋值操作、条件判断、循环等。
通常来说,如果有两个代码块 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层的嵌套
尽可能地减少代码的嵌套深度。尽可能地保持最多两层代码块的嵌套。
当一个函数的嵌套层数超过两个时,就需要考虑将子代码块移到单独的函数中。
特殊情况除外。