Working Effectively with Legacy Code - Michael C. Feathers

When people saw this book at work, they laughed. I'm not entirely sure if this was due to the title of the book, or the fact that the front cover shows a Difference Engine. However, by the terms of this book, the code at work is legacy code.

In the context of this book, "legacy code" is any code that's hard to modify, specifically because it doesn't have tests around it, and moreover tests are hard to put in place. In other words, it's one of those books, in the Test-Driven Development, Pair Programming, Agile Blah space. However, it does make a pretty convincing argument - if you want to be able to confidently modify a complex existing system without introducing new bugs, you really want tests, and by introducing tests future changes become easier, and the changes you make to make the code testable probably improve the design anyway.

The book does have the right mindset for dealing with snarled-up codebases, in that it encourages incremental changes that preserve existing behaviour, and never suggests "If you see a big chunk of code that seems to make no sense, why not just throw it away and rewrite it?", no matter how tempting that might be. It acknowledges that sometimes making the code clean enough to put tests on needs to be done, without tests, so the safest thing to do is do the minimum, safest change to get it into a state you can stick tests on. It's all about cautiously, incrementally getting there, and not really worrying if things look a bit ugly in the meantime if it's helping you to eventually reach a better state.

However, just like the TDD book, it seems unable to avoid going into mind-numbing detail, as if your reader is an idiot. There's a great, short book trapped in there somewhere. The chapter headings promised the world, while the contents are prosaic - "I'm Changing the Same Code All Over the Place" leads to the suggestion to refactor your code to remove redundancy. *sigh*.

Just like the TDD book, it doesn't cover the genuinely difficult cases. For example, multithreading doesn't get a look in, which is a real shame, since that increases the difficulty in refactoring code by an order of magnitude. Similarly, it's a real nightmare if the memory manageement model has got lost.

Overall, it's a pretty good book, and it has plenty of valuable things to say. Unfortunately, it suffers what seems to be the standard Agile Book Disease, in that it attacks simple problems with gusto and in (far too much) depth, without actually covering the difficult cases.

Posted 2014-04-13.