3.1. 战术编程

大多数程序员以我称为战术编程的心态来进行软件开发。在战术方法中,您的主要重点是使某些功能正常工作,例如新功能或错误修复。乍一看,这似乎是完全合理的:还有什么比编写有效的代码更重要的呢?但是,战术编程几乎不可能产生出良好的系统设计。

战术编程的问题是它是短视的。如果您是战术编程人员,那么您将尝试尽快完成任务。也许您有一个艰难的期限。因此,为未来做计划不是优先事项。您不会花费太多时间来寻找最佳设计。您只想尽快使某件事起作用。您告诉自己,可以增加一些复杂性或引入一两个小错误,如果这样可以使当前任务更快地完成,则可以。

这就是系统变得复杂的方式。如 上一章 所述,复杂度是递增的。不是使系统复杂的特定事物,而是数十或数百个小事物的积累。如果您进行战术编程,则每个编程任务都会带来一些此类复杂性。为了快速完成当前任务,他们每个人似乎都是一个合理的折衷方案。但是,复杂性迅速累积,尤其是如果每个人都在战术上进行编程的时候。

不久之后,某些复杂性将开始引起问题,并且您将开始希望您没有采用这些早期的捷径。但是,您会告诉自己,使下一个功能正常工作比返回并重构现有代码更为重要。从长远来看,重构可能会有所帮助,但是肯定会减慢当前的任务。因此,您需要快速修补程序来解决遇到的任何问题。这只会增加复杂性,然后需要更多补丁。很快代码变得一团糟,但是到现在为止,情况已经很糟糕了,清理它需要花费数月的时间。您的日程安排无法容忍这种延迟,解决一个或两个问题似乎并没有太大的区别,因此您只是在战术上保持编程。

如果您从事大型软件项目的时间很长,我怀疑您在工作中已经看到了战术编程,并且遇到了导致的问题。一旦您沿着战术路线走,就很难改变。

几乎每个软件开发组织都有至少一个将战术编程发挥到极致的开发人员:战术龙卷风。战术龙卷风是一位多产的程序员,他抽出代码的速度比其他人快得多,但完全以战术方式工作。实施快速功能时,没有人能比战术龙卷风更快地完成任务。在某些组织中,管理层将战术龙卷风视为英雄。但是,战术龙卷风留下了毁灭的痕迹。他们很少被将来必须使用其代码的工程师视为英雄。通常,其他工程师必须清理战术龙卷风留下的混乱局面,这使得那些工程师(他们是真正的英雄)的进步似乎比战术龙卷风慢。

Most programmers approach software development with a mindset I call tactical programming. In the tactical approach, your main focus is to get something working, such as a new feature or a bug fix. At first glance this seems totally reasonable: what could be more important than writing code that works? However, tactical programming makes it nearly impossible to produce a good system design.

The problem with tactical programming is that it is short-sighted. If you’re programming tactically, you’re trying to finish a task as quickly as possible. Perhaps you have a hard deadline. As a result, planning for the future isn’t a priority. You don’t spend much time looking for the best design; you just want to get something working soon. You tell yourself that it’s OK to add a bit of complexity or introduce a small kludge or two, if that allows the current task to be completed more quickly.

This is how systems become complicated. As discussed in the previous chapter, complexity is incremental. It’s not one particular thing that makes a system complicated, but the accumulation of dozens or hundreds of small things. If you program tactically, each programming task will contribute a few of these complexities. Each of them probably seems like a reasonable compromise in order to finish the current task quickly. However, the complexities accumulate rapidly, especially if everyone is programming tactically.

Before long, some of the complexities will start causing problems, and you will begin to wish you hadn’t taken those early shortcuts. But, you will tell yourself that it’s more important to get the next feature working than to go back and refactor existing code. Refactoring may help out in the long run, but it will definitely slow down the current task. So, you look for quick patches to work around any problems you encounter. This just creates more complexity, which then requires more patches. Pretty soon the code is a mess, but by this point things are so bad that it would take months of work to clean it up. There’s no way your schedule can tolerate that kind of delay, and fixing one or two of the problems doesn’t seem like it will make much difference, so you just keep programming tactically.

If you have worked on a large software project for very long, I suspect you have seen tactical programming at work and have experienced the problems that result. Once you start down the tactical path, it’s difficult to change.

Almost every software development organization has at least one developer who takes tactical programming to the extreme: a tactical tornado. The tactical tornado is a prolific programmer who pumps out code far faster than others but works in a totally tactical fashion. When it comes to implementing a quick feature, nobody gets it done faster than the tactical tornado. In some organizations, management treats tactical tornadoes as heroes. However, tactical tornadoes leave behind a wake of destruction. They are rarely considered heroes by the engineers who must work with their code in the future. Typically, other engineers must clean up the messes left behind by the tactical tornado, which makes it appear that those engineers (who are the real heroes) are making slower progress than the tactical tornado.