时间与变化

当新手学习编程时,其代码的生命周期通常以小时或天为单位。编程作业和练习往往是一次性编写的,几乎没有重构,当然也没有长期维护。这些程序在编写后同行不会重新构建或再次执行。这在教学环境中很常见。也许在中学或中学后的教育中,我们可能会找到团队项目的课程或需要实操的论文。如果是这样,这样的项目可能是唯一一次学生代码的寿命超过一个月左右。这些开发人员可能需要重构一些代码,也许是为了响应不断变化的需求,但他们不太可能被要求处理来应对外部环境的大变化。

我们还在常见的行业环境中找到了短期代码的开发人员。移动应用程序的生命周期通常很短,并且无论好坏,完全重写都比较常见。初创公司的工程师可能正确地选择专注于近期目标而不是长期投资:公司可能活得不够长,因此无法从回报缓慢的基础设施投资中获益。一个持续创业的开发人员,虽然拥有10年的开发经验但是很少或没有维护任何预计存在超过一两年的软件的经验,这也是很正常的。

在另一端,一些成功的项目实际上具有无限的生命周期:我们无法合理预测Google 搜索、Linux 内核或 Apache HTTP Server项目的终点。对于大多数Google项目,我们必须假设它们将无限期存在——我们无法预测何时不需要升级我们的依赖项、语言版本等。随着它们生命周期的增长,这些长期存在的项目最终会给他们带来与编程任务或初创公司开发不同的感觉。

参考图1-1,它展示了这个“预期寿命”范围两端的两个软件项目。对于从事预期寿命为数小时的任务的程序员来说,什么样的维护是合理的?也就是说,如果你在处理只需要执行一次的Python脚本时出现了新版本的操作系统 你是否应该放弃你正在做的事情并升级?当然不是:升级并不重要。但在图示的另一端,谷歌搜索被困在我们1990年代的操作系统版本上将是一个明显的问题。

生命周期和升级的重要性

在代码寿命周期图中,低点和高点间存在过渡阶段。这个过渡阶段存在于一次性项目和持续数十年的项目间,这个过渡阶段发生了转变:项目开始对不断变化的外部性做出反应。对于从一开始就没有升级计划的项目,这种转变是非常痛苦的,有三个原因,每个原因都会使其他原因更加复杂:
• 你正在做该项目尚未完成的任务,接下来的任务会有很多不确定性。
• 尝试进行升级的工程师可能不具备此类任务的经验。
• 升级的规模通常比平时大,一次进行多年的升级而不是逐步迭代。

因此,在实际经历过一次这样的升级(或中途放弃)之后,我们通常会高估进行后续升级的成本并决定“再也不会升级了”。这样的公司最终只能扔掉旧代码并重写他们的代码,或者决定永远不会再次升级。与其采取这样不得已而为之的方法来避免做痛苦的升级,有些情况下更好的做法是做好准备让升级变得更加轻松。这一切都取决于升级的成本、升级带来的价值以及该项目的预期寿命。

不仅要经历第一次重大升级,而且要让项目达到可以稳定前进的地步,这才是项目长期可持续性的本质。可持续性需要规划和管理必要变更带来的影响。对于Google的许多项目,我们相信我们已经实现了这种可持续性,主要是通过反复试验。

那么,具体而言,短期代码编程与预期寿命更长的代码编程有何不同?随着时间的推移,我们需要更加意识到“碰巧工作”和“可维护”之间的区别。没有完美的解决方案来识别这些问题。这是不幸的,因为保持软件的长期可维护性是一场持久战。