知乎上有个问题,如何辨别一个程序员水平的高低?就这几年 Review 代码的体感,忍不住就工程素养这个话题吐两句槽,正好作为“好好写代码”系列的第二篇。
思维体系
水平差的程序员往往在“抽象”上做的不好。
什么是抽象能力呢?简言之,就是分门别类、触类旁通的能力。通过大量实践和书籍输入,将所解决过的问题进行正交分解,分解过的元知识多具有很好地复用性;再利用这些元知识,进行组合推演,创造性的解决新遇到的问题。即归纳和演绎。
体现在做系统设计时,会对涉及到的概念进行精确描述:对于单个概念,定义好其内涵外延;对于多个概念,梳理好其层次关系。映射到代码上,就是不同类的职责清晰划分。
如果抽象能力不行,会有什么问题呢?
- 知识体系离散。不能将学到的散乱知识分门别类,梳理出体系。反应在定位问题上,东一下、西一下,看不到问题的脉络,自然也就分析不出问题的原因。
- 与人交流困难。不能对一个问题在不同抽象层次上进行阐释,给别人讲其解决方案时,就会自然倾向使用“伪代码”式这种最底层抽象层次进行描述,暴露大量实现细节,如果对方和你共享的上下文很少,就很难搞懂在说啥。因此,需要对具有不同上下文的人,对问题进行不同的泛化(也是抽象)处理,通过抽象适当剪除上下文,直到能跟他对齐为止。
- 代码晦涩难懂。至少可以从两方面来理解。其一,从方案设计上,对于一个问题,如果能找到对其更本质的抽象,那么对应的代码实现一定更加简洁易懂。其二,从代码组织上,如果一个问题很复杂,但是能进行合理拆解、逐层抽象,就一定比“摊大饼”式组织更容易理解。
工程素养
水平差的程序员往往对代码“不讲究”,这其实是工程素养差的表现。
那不讲究的代码是什么样的呢?比如,同样含义的变量使用不同的名字、对偶功能(如增删改查)命名不成体系、相似代码不断重复而没有重用、反常逻辑没有任何注释、子模块间头重脚轻、好好的封装被改出几个洞等等(关于如何命名可参考我之前的一篇文章[1])
这种不讲究有什么问题吗?
- 复杂度爆炸。软件工程最主要的一个目标就是控制复杂度。因为工程化的本质是为了解决规模化所引入的复杂度。而不讲究的代码,通过糟糕的命名、随意的破墙穿洞、混乱的数据流,使代码的复杂度指数级上升,以至于最后需要推倒重来。
- 易藏污纳垢。不美观、不符合直觉、不直白的代码,非常容易掩藏一些不易察觉的 bug 。写的时候发现不了,Reviewer 也很难看出来。到后来,就会完全变成一个黑盒,纵使代码在那,你看得懂每条语句,连起来后却不知道他在干啥。
- 让同事抓狂。好的代码读起来有一种韵律感,能让人一天都很开心;不好的代码看起来就像吃了苍蝇,能破坏一天的好心情。而最让人难受的是,这种不讲究的人出活还贼快,KPI 还贼好,但是他升上去后,哪管洪水滔天。关爱同事,少堆屎山,从我做起。
但需要声明,不同的活对讲究程度要求是不一样的,那如何抉择呢?这里我想引入一个参考度量:生命周期。生命周期越长的代码,一定要写的越干净;临时使用代码,比如小脚本,就可以不讲究一些。反过来,也正是干净的代码才能成就超长的生命周期。
大家看别人和自己过去的代码时,有哪些想吐槽的呢?欢迎在留言区讨论。
我是青藤木鸟,一个喜欢摄影的程序员,大家可以看看每篇文章的题图。如果感觉还不错,就点个在看分享给更多人吧。另外,我做了一个专门讨论分布式系统和数据库的论坛,欢迎同好来玩,点阅读原文可以直达。
参考资料
[1]
好好写代码之命名篇: https://www.qtmuniao.com/2021/12/12/how-to-write-code-scrutinize-names/
题图故事
莫尔道嘎国家森林公园,垂直俯拍,总会有惊喜往期文章:计算机极简公开课推荐 《DDIA 逐章精读》小册 好好写代码之命名篇——推敲