说到一个现象我们大多数人都会同意:无论任何软件项目,做一段时间之后,就会充斥着烂代码。为什么会这样呢,是谁生产了这些烂代码?

给别人提供建议的时候,不少人喜欢让别人换一个平台,重来一次。比如看见别人在 Windows 上遇到一点问题,他会建议“不如换 Linux”;在 .NET 上遇到问题,有人会说“还是 Java 更好、Go 更酷”。那么,对于烂代码的软件项目,如果我们另起炉灶,重新来过,就能做出一个代码更好的项目吗?事实上,在具体的问题面前,这只是一种逃避现实的“旁观者”心态——对于旁观者来说,反正又不是“我”的项目,管它呢!

我们来看一下烂代码是怎么产生的,之后再去探讨为什么不应该容忍烂代码。

烂代码的生产者

陈皓在如何重构“箭头型”代码一文中探讨了重构优化下面这种“箭头”形状代码的一些方法。我们在这里思考一下这样的代码是怎么造成的。

箭头型代码

上面的代码是一个注册表单的服务器代码,其中最重要的逻辑是最中间的create_user,用来注册一个新用户,可整个方法却被各种错误判断遮住了,颇有一种“喧宾夺主”的感觉。一般来说,这类代码的产生有两个原因:

  • 一开始写的人就写成了这样
  • 后来加功能、改问题的人改成了这样

初次写成这样的原因也很简单,因为上面层层递进的逻辑关系与程序员对这个问题的理解非常匹配,水平所限也没有更好的写法了。另外一个原因是,写好、自测完事之后也没有来得及多看一眼,就推送到代码库着急着下班了——毕竟再不下班就赶不上末班车了。

想象一下,如果这个逻辑里出现一个问题,修问题的人需要小心谨慎地将整个方法都读一遍,才有可能有一些线索。如果是要这坨代码上再加功能——加一些新的限制条件,比如验证码,那又是新的一层if……如果要修改允许的用户名的长度,就既要改长度验证,又要改对应的正则表达式了。要修改分散在多处却又相关的逻辑时,非常容易漏掉一些。在这样的代码上无论是增加新功能还是修改已有逻辑都会是一件痛苦的事。没有人希望在它这里多呆一秒的,因此后续改这个代码的人也只好来去勿勿。

从一开始它被加进代码库里,到后续的增加新功能、修改已有功能,或是修复问题时,都没有人再去完善它了。这段烂代码就永远地留在了产品里。

到底谁生产了烂代码?在回答这个问题之前,我们先来检视一下自己:是不是很次回去看自己几个月之前写的代码,也都觉得很烂?——如果你有这样的习惯,或者偶尔有那么一次在出现问题,你本想找到当初的作者大骂一顿却尴尬地找到了自己的名字的时候!

遗憾的是,我们都是烂代码的生产者。

烂代码的卫道士

更遗憾的是,我们常常不光是烂代码的生产者,还是烂代码的卫道士。一起来看看下面的场景,是不是在你日常的团队协作中似曾相识:

我的代码最棒了,别人的都是垃圾

前半句来自程序员的自豪感,后半句来自程序员的“王的鄙视”。这太常见了——从用 Linux/macOS 的人鄙视用 Windows 的人,从用 Java 的人鄙视用 .NET 的人,码界的鄙视链无处不在。即使在同一个团队里,也会出现用机械键盘的鄙视用薄膜键盘的。抱着这种心态的程序员,别人只好敬而远之。他的代码?没有人管的,让他自生自灭去吧!

这是别人写的代码,我不能改

这就是用来对付上面那种人的一种简单有效的方法。“惹不起,我还躲不起吗?”,既然现在要改一下逻辑,不如复制一份再改吧!在现实中,即使队友不是上面的那种人,也会大量出现随意重复现有代码的做法。人们有一万种理由这样做:防止冲突,防止原有逻辑被别人改坏了,防止改坏了原有逻辑,原有代码用了一个静态变量……最恶心的是,别人的代码里出现了 Bug,也只能等到他自己来修:反正修好了他也不会感激我,修坏了那我就没完了。

不是听说他很牛吗,他也这样写,那肯定没问题

在码界,有人鄙视,也会有人景仰。编码工作也是一种技艺,初学者对有经验的前人所怀有的景仰之心与武侠世界里小生对前辈的仰慕与推崇并没有区别。“既然前辈写的箭头代码那么气势恢宏,那我怎能不追随之呢”?还有一个常见情况是,看不懂前辈的代码,但用起来就是好用——简直太神奇了。这越发引发了后来者莫名的顶礼膜拜。

今天没空了,改天再回来改

这大概是产生烂代码的最直接的原因吧。一个 Hello World 如果给一个月时间,相信随便一个程序员也能雕出朵花儿来。“既然产品经理已经站在身后逼宫了,就只好先这样了。”这可能是程序员们更经常遇到的现实情况。很明显,对于产品经理来说,他此刻更关心“代码要写完”,至于写的好不好,这很重要吗?对了,谁能说一下,“改天”是哪天?

代码行数太少,不准提交

最近有个江湖段子在网上盛传,说是做某团队 A 工作效率高、产品质量好;作为对比,有的团队 B 却在天天加班修不完的 Bug。不久之后,团队 A 被解散了,因为老板觉得他们不够努力。我多希望这只是个笑话。我们来看另一段代码:

用 Sleep 减慢程序

只能说,程序员被逼到这个份上,真是行业不幸。


看完这许多的情境,不知读者有怎样的感触。烂代码并不是凭空生成,而是有人为之,有人随之,有人不得不为之。那么,我们有何面目去批评他人生产了太多的烂代码?如今作为产品经理,作为团队领导,架构师或是高工主程的你,又该如何行动去改善这一情况?

不过,在行动之前——如果准备行动的话,不妨先思考另一个问题,为什么不应该容忍烂代码?大多数情况下,人们也就是口头骂骂“这段代码简直太烂了”,一边骂一边在其中改完了要改的东西,就赶紧逃掉了,接着也就一如往常开心地工作了。所以,看起来人们并非不能容忍烂代码嘛,既然如此,烂代码一定需要被改善吗?