3.1 战术性编程
大多数程序员以一种我称之为战术性编程(tactical programming)的思维方式对待软件开发。在战术性的方法中,你的主要关注点是让某些东西工作起来,比如一个新功能或一个bug的修复。乍一看,这似乎是完全合理的:还有什么能比写出能工作的代码更重要的?然而,战术性的编程使你几乎不可能作出一个好的系统设计。
战术性编程的问题在于,这种方式是目光短浅的。如果你在进行战术性编程,你就会试图尽可能快地完成一项任务。也许你有一个硬性的最后期限。因此,对未来的规划并不是一个优先事项。你不会花很多时间去寻求最好的设计;你只想尽快让代码工作起来。你告诉自己,如果能让当前的任务更快地完成,那么增加一点复杂性或引入一两个小麻烦都是可以的。
这就是系统变得复杂的原因。正如上一章所讨论的,复杂性是逐步增加的。使系统变得复杂的不是某一件特定的事情,而是几十或几百件小事情的积累。如果你采取战术性的方式编程,每个编程任务都会贡献一些这样的复杂性。为了快速完成当前的任务,每一项都可能看起来是合理的妥协。然而,复杂性会迅速积累,特别是如果每个人都在战术性地编程。
不久之后,之前引入的一些复杂性会开始造成问题,你会开始希望你没有采取早期的那些捷径。但是,你会告诉自己,让下一个功能正常运行比回头重构现有代码更重要。从长远来看,重构可能会有所帮助,但它肯定会拖累当前的任务。所以,你要寻找快速的补丁来解决你遇到的任何问题。这只会造成更多的复杂性,然后需要更多的补丁。很快,代码就成了一团糟,但此时事情已经糟糕到需要花几个月的时间来清理。你的日程表不可能容忍这样的拖延,而且修复一两个问题似乎也不会有什么不同,所以你只能继续战术性地编程。
如果你在一个大型软件项目上工作了很长时间,我想你已经见识到了战术性编程的工作,并经历了由此产生的问题。一旦你开始走战术性的道路,就很难改变。
几乎每个软件开发组织都至少有一个将战术性编程发挥到极致的开发者:“战术龙卷风”。“战术龙卷风”是一个多产的程序员,他编写代码的速度比其他人快得多,但工作方式完全是战术性的。当涉及到实现一个快速功能时,没有人比“战术龙卷风”完成得更快。在一些组织中,管理层将“战术龙卷风”视为英雄。然而,“战术龙卷风”留下了破坏的痕迹。他们很少被那些将来必须与他们的代码打交道的工程师们认为是英雄。通常情况下,其他工程师必须收拾“战术龙卷风”留下的烂摊子,这让人觉得那些工程师(他们才是真正的英雄)的进展比“战术龙卷风”要慢。
Last updated