16.1 保持战略性
Last updated
Last updated
第三章介绍了战术性编程和战略性编程之间的区别:在战术性编程中,主要目标是让某些东西能用,即使这会导致额外的复杂性;在战略性编程中,最重要的目标是产生一个优秀的系统设计。战术性的方法很快就会导致混乱的系统设计。如果你想拥有一个易于维护和增强的系统,那么“能用”并不是一个足够高的标准;你必须把设计放在优先位置,并从战略上考虑。这个想法在你修改现有代码时也适用。
不幸的是,当开发人员进入现有的代码进行变更时,如修复bug或开发新功能,他们通常不会从战略上考虑。一个典型的思维方式是:“我可以做什么最小的改动来满足我的需要?” 有时,开发者这样做的理由是他们对被修改的代码不放心;他们担心较大的改动会带来更大的风险,会引入新的bug。然而,这导致了战术性的编程。每一个最小的改动都会引入一些特殊情况、依赖关系或其他形式的复杂性。结果是,系统设计变得越来越糟,问题随着系统的演化一步步积累。
如果你想保持一个简洁的系统设计,你必须在修改现有代码时采取战略性方法。理想的情况是,当你完成每一次变更后,系统将拥有如果你在一开始设计时就考虑到这一变更而拥有的结构。为了实现这一目标,你必须抵制快速修复的诱惑。相反,考虑一下当前的系统设计是否仍然是最好的,鉴于所期望的变化。如果不是,就重构系统,使你最终得到最好的设计。通过这种方法,系统设计会随着每一次修改而改进。
这也是介绍的投资心态的一个例子:如果你投入一点额外的时间来重构和改进系统设计,你最终会得到一个更简洁的系统。这将加快开发速度,而且你将收回你在重构中投入的精力。即使你的某次具体的变更不需要重构,你仍然应该在代码中留意那些你可以修复的设计缺陷。每当你修改任何代码时,试着在这个过程中至少找到一种方法来改进系统的设计。如果你没有使设计变得更好,那么你很可能正使它变得更糟。
正如在第三章中所讨论的,投资心态有时会与商业软件开发的现实相冲突。如果用“正确的方法”重构系统需要三个月的时间,而用快速和肮脏的方法修复只需要两个小时,那么你可能不得不采取快速和肮脏的方法,特别是当你在紧迫的期限内工作时。或者,如果重构系统会造成不兼容,从而影响到其他许多人和团队,那么重构可能就不切实际了。
尽管如此,你应该尽可能地抵制这些妥协。问问自己:“在我目前的限制条件下,这是否是我能够创造一个简洁的系统设计的最好办法?”也许有另一种方法可以和3个月的重构几乎一样简洁,但可以在几天内完成?或者,如果你现在没有能力进行大规模的重构,让你的老板分配时间给你,让你在当前的DDL之后再来做。每个开发组织都应该计划在清理和重构上花费总工作量的一小部分;从长远来看,这项工作将收回成本。