《代码大全2》二
第5–9章是全书密度最高的章节之一,McConnell 把"创建高质量代码"拆成了几个可操作的维度,读下来我最深的体会是:我们写的每一行代码,本质上都在做设计决策——只是大多数人没意识到。
先从最小单位的决策说起:命名。第5章讲变量命名,听起来像编码规范,实际讲的是设计思维。作者的核心论点是,好的变量名应该自文档化——读代码的人不需要注释就能理解意图。变量名要准确描述它代表什么,而不是怎么用;长度应该和作用域成正比;要远离模糊的缩写和"data""info""temp"这类通用词。这让我反思自己的习惯——为了"简洁"常用 ctx、mgr、proc这类缩写,当时觉得清晰,三个月后回看就是天书。命名不是给编译器看的,是给下一个读代码的人看的,包括未来的自己。一个好的变量名能省掉一行注释,甚至省掉一次bug排查。
命名之后是变量的生命周期管理。第6–9章围绕初始化、作用域、存活时间和绑定时间展开,贯穿其中的一条主线是:变量的生命周期越短、作用域越小,代码越安全。全局变量之所以被诟病,不是因为它不好用,而是它打破了局部性,让任何地方都能修改状态,debug时你永远不知道谁改了什么。作者还提了一个容易被忽略的概念——绑定时间:一个值在什么时候被确定?编译时、加载时还是运行时?绑定得越晚,灵活性越高,但可读性和可预测性越低。硬编码一个配置、读配置文件、动态下发,本质上就是这个取舍。以后写代码我会多问自己两个问题:这个变量的作用域能不能再小一点?这个值的绑定时间能不能再早一点?两个答案都是"能"的话,代码质量就已经超过平均水平了。
再往上是控制流。第7–9章讲控制结构和条件语句,合在一起讲的是一个道理:代码的执行顺序应该和人的阅读顺序一致。正面逻辑先写、异常提前返回、嵌套不超过三层、循环体保持简短——这些不是风格偏好,是认知负荷管理。作者举了一个让我印象很深的例子:一段嵌套了五层的 if-else,逻辑上没错,但没人能一眼看懂。重构的方式不是加注释,而是用 guard clause 把异常情况在开头就处理掉,正常逻辑留在主干。这样代码的"故事线"就清晰了:先做合法性检查,通过就走主流程,一目了然。回想自己写过的代码,最容易被吐槽的就是嵌套太深,以后可以用一个简单的规则约束自己:函数内嵌套超过两层就该停下来想想,是不是该拆函数了,或者是不是该用提前返回了。
这些原则不是抽象的。之前维护过一个老项目,里面有一个300行的函数,嵌套了六层 if,变量在中间才初始化、末尾才用到,命名全是 a1、tmp2、flag3。当时改一个bug引入了三个新bug,根本原因就是变量作用域太大、控制流太绕、命名没有语义。读完这部分才系统地理解:这不是"代码写得不好"这么简单,而是违反了变量设计、控制流设计的基本原则。如果当时有人按这些原则写过,维护成本至少降一半。
所以第2部分读完,最大的收获是:代码质量不是靠"写完再改"改出来的,而是从第一行变量声明开始就在做对的事。命名传递意图、作用域最小化、控制流扁平化——这些看似基础的东西,恰恰是区分"能跑的代码"和"能维护的代码"的分水岭。后面几部分会深入到更具体的编码场景,但地基已经打在这里了。
浙公网安备 33010602011771号