Working Effectively With Legacy Code
by Michael C. Feathers
Feather's adopts an extreme position on the definition of legacy code: code that doesn't have a complete suite of unit tests that support test driven development. This makes almost everything "legacy".
Still, he makes the definition work, and in the process creates an engaging book that presents one of the few good arguments I've seen that we're not stagnating, that software development really is making progress. Feathers concludes that the underlying issue that complicates and clutters all big systems is, in the end, dependency: everything comes to depend on everything else, and so maintenance increasingly leads toward Big Ball of Mud.
I've been intrigued by this problem for years. It's chronic in hypertext system design. You have core classes that represent core abstractions in your system: Hypertext, Node, Link. They're powerful, so they're big. They're central, so everything depends on them. Soon, every little improvement in functionality requires recompiling the world. Worse, improving one part of the system can conceivably break anything: changing the spell checker might break the registration dialog.
Sound like an exaggeration? It's not. Read my HT02 paper on Storyspace I for some of actual examples. You ship code: zaniness ensues.
Feathers presents concrete steps toward incremental improvement through refactoring and ubiquitous scaffolding.