书架上那本《代码大全》第二版,是2010年刚入行时买的。当时读得囫囵吞枣,很多内容看不懂,看完只记住了"变量要好好命名"这一条。五年过去了,写了几十万行代码,踩了无数坑,春节假期翻出来重读,才发现这本书的价值被我严重低估了。
Steve McConnell写的这本书,不是教你某门语言的语法,而是教你"怎么写好代码"这件事本身。它覆盖了从需求、设计、编码到测试的整个软件开发流程,其中关于编码细节的部分,尤其值得反复读。
变量命名的学问
五年前我觉得变量命名就是"见名知意",这次重读才发现里面有大学问。McConnell说,变量名的长度应该和它的作用域成正比——循环变量用i、j没问题,但全局变量如果叫data就太糟糕了。
还有一个我以前忽略的点:变量名应该描述"是什么"而不是"怎么实现"。比如userList比userArray好,因为如果以后改成用集合存储,名字就不用改。布尔变量应该用is、has、can这样的前缀,让人一看就知道是真假值。
回想自己写的代码,确实有很多命名糟糕的地方。比如把$temp用在五个不同的地方,比如把$data当万能变量名用。今年重构的时候,第一件事就是把这些名字都改过来。
函数设计的原则
关于函数,McConnell提出了几个原则,我深以为然。第一,函数的内聚性要高——一个函数只做一件事,而且只通过一个入口做这件事。第二,函数的长度要适中——太长的函数难以理解,太短的函数又会增加调用开销,他建议一般不超过两屏代码。
第三,函数的参数不要太多——超过七个就应该考虑用结构体或对象封装。第四,函数名应该用动词加宾语的形式,比如getUserById()而不是user()。
我对照检查了自己的代码,发现有个处理用户注册的函数,居然有三百多行,里面干了验证、入库、发邮件、记日志四件事。这样的函数,出了Bug都不知道从哪儿查。按照McConnell的原则,应该拆成四个小函数,每个只做一件事。
防御式编程
防御式编程是我以前完全忽略的一章。McConnell说,好的程序员应该假设所有输入都是恶意的,所有外部调用都会失败,然后在这种假设下写代码。
具体做法包括:校验所有外部输入、用断言检查内部假设、合理处理错误码、不要轻信其他函数的返回值。比如从数据库查用户,不能假设一定能查到,要处理查不到的情况;调用第三方API,不能假设一定成功,要处理超时和错误响应。
我以前写代码,经常省略错误处理,觉得"这种情况不会发生"。但线上环境什么都可能发生,省略错误处理的代码,就像没系安全带开车,不出事还好,出事就是大事。
总结
重读《代码大全》,最大的感受是:编程不只是让代码跑起来,更是让代码可读、可维护、可扩展。五年前我追求的是"能实现功能",现在我追求的是"写好代码"。这本书值得每个程序员放在案头,每隔几年重读一次,每次都会有新的收获。
评论(0)
暂无评论,快来抢沙发~
评论功能仅对会员开放,请先登录
登录