转载

源码的寿命

  英文原文:Longevity of Source Code

  看看你现在日常工作中的代码。已经运行了多久了?代码有多老了?有六个月?一年?可能都有五年这么久了吧?十年?二十年呢?!这样的代码有多老了?不到 10%?还是一半?亦或者已经有 90% 了?为了了解这些问题的答案,我对代码的存活时间做了一些调查。

  软件考古

  在已经存在很多年并且已经有自己的一系列源码运作的公司里,编写软件就像是类似软件学考古的一种磨练,深入研究应用就像在挖掘一个古老的城市,逐层的揭开过去种种的面纱。

  一旦你开始钻研一些封装好的微型服务,就算是已经开始研究过去:也许残留着有对公司面向服务体系架构的第一个尝试;现在就是对伴随着复杂业务逻辑的整体服务并且捆绑了 Spring 的总结。深入挖掘后我们回到了 EJB 的时代;由于开发者已经丧失了对它们理解的欲望,一些已经被遗忘好久的 beans 仍然依附于生活。再往下就是整体系统骨架的地方了。

  如果没有被打破,就不要去修理它

  如此糟糕的代码是什么?不用怀疑它带有如此强烈的目的性。至少有一些是这样的。

  如果你查看你一年期所写的代码并且发现没有什么可以改变的,你这一年算是没有成长。

  我们一直在学习:更好的理解领域,更好的理解领域解决方案,新的架构方式,新的工具,新的方法,新的标准以及新的思路。你一年前的写代码在某些地方可以进行改进这是很正常的,但是,有多少代码你回过头去进行改进了呢?

  旧代码是会变得越来越难修改的。如果一个业务需求的变更让你必须回头修改最原始的 EJB,你会怎么办?你会去修改你十多年前写的代码吗?或者花时间去分析其中需要修改的部分?或者干脆每次都新建一个新的小模块来解决?这些修改的代价是很昂贵的。

  而现在的问题是:偿还这种“技术债”是正确的事,但是修改以前的代码一般都会比你上周写的或者上个月写的东西慢。如果以前代码应该修改的地方你没有及时去修改,这将影响你开发新的功能。最糟糕的是我们有时会明明知道有些地方我们做错了,但是还是保持他长期运行。这些方法在当时我们认为是对的,只是现在看起来是错了。

  我们代码的寿命?

  我对大量源代码做过调查,其中包括商业以及开源的,设计各种语言(Java,C#,Ruby)。总体上,这些代码都遵循一个相似的规则:

  大约 70% 的代码,在你写后的 12 个月内一直在使用,没有发生修改。

  也许并不奇怪,代码完成之后的头几个月改动是最频繁的。再往后似乎就进入了一种维护模式,改动量变得相对较少。

源码的寿命

  我发现这玩意儿实在太有趣了:大约 75% 的代码在我完成一年后仍然是原来的样子。你可以设想一下我现在对于这个问题理解了多少,想像一下那些早就忘掉的设计思想,改变了的架构愿景,新的工具和仍能重构使用的库。想像一下当年写下的那一行行代码在今天又能有多大的改进余地。而且,在那些仍然遗留着类似技术债的代码库里,就算我们一直在孜孜不倦地偿还,也没见到老的代码新了多少。

  我是怎么做的这项分析?这要归功于 Git 的魔力,它使这项分析变得很简单。只要对整个仓库做一次 git blame 的递归,就能够列出针对分支中的每一行代码的 commit 号、提交人、提交时间。配合上一些 shell 脚本技巧就能得出每月或每天的统计数字:

git ls-tree -r -rz --name-only HEAD --  xargs -0 -n1 git blame -f HEAD  sed -e 's/^.* /([0-9]/{4/}-[0-9]/{2/}/)-[0-9]/{2/} .*$//1/g'  sort  uniq -c

  按月份统计,截止到今天,以上输出的这个表格是关于每一行代码最近被改动过的时间。不过,我也可以很容易地把时间往前推,比如把时间推到 2015 年的开始:

git checkout `git rev-list -n 1 --before="2015-01-01 00:00:00" master`

  把时间往前推之后,重新递归运行一次 git blame,通过比较每个月得出的结果,我就能知道有多少代码是在 2015 年之前写的。经过更加详细的分析,我也能得出某个月中最新修改的代码行数量怎样随着时间变化而变化,进而知晓代码衰退得有多快(多慢)。

  结论

  代码写出来无非是为了实现某个意图,递送一些商业数据,但很快这就变成一种负债了。年代愈发久远,原来的代码就越腐朽而越难以修改,根据上面的分析,你很容易明白为什么一个代码仓库能够存在将近十年之久,里面的代码为什么都是些老古董:每年的改动量少之又少,它们就是躺在那儿没人管,自始至终我们就只是在不断地往里面添加新的遗产——它们中的大多数即使到了下一个年头你仍然还是可以找到的。

  对于这种情况,我们可以做些什么?过时的代码只会不断堆积,这似乎就是软件的自然法则,依我个人经验来看,即使大家齐心协力对这些代码进行重构,似乎也收效甚微。我们还能做些别的么?或者我们干脆坦然接受越是年代久远的代码就越难修改的这一事实?还是我们需要找到一个办法,鼓励软件有一个更短的半衰期,以更快地得到重写。

正文到此结束
Loading...