How Much Legacy Code Have You Written This Week?

I recently bought a copy (based on a recommendation) of Michael Feathers’ 2005 book Working Effectively with Legacy Code.

This excellent technical book is largely a compendium of refactoring strategies to help software developers insinuate unit tests into existing code.

What I found most striking, though, is a position stated right at the start of the book.

Most programmers have a broadly intuitive idea what “legacy code” means. It’s typically a euphemism for code that they resent, because it’s old and crufty and they have to maintain it unwillingly. There may be a hint of the positive meaning of “legacy”—code handed down to you that does at least work, which is why you have to maintain it. In my mind there’s also a suggestion that the code is alien in some way—written for an obsolete platform or in an obsolete language—which contributes to the difficulty of managing it.

Feathers dismisses most of these possible definitions, writing

In the industry, legacy code is often used as a slang term for difficult-to-change code that we don’t understand. But over years of working with teams, helping them get past serious code problems, I’ve arrived at a different definition.

To me, legacy code is simply code without tests.

[…] With tests, we can change the behavior of our code quickly and verifiably. Without them, we really don’t know if our code is getting better or worse.

That’s pretty uncompromising, but it certainly gives you perspective.

If you take this point of view, then every line of code you write that lacks tests—proper tests that properly test, and that other people can run—is an immediate, direct contribution to the sludgy mountain of cruddy code that nobody really understands and that probably doesn’t work.

(Of course, code with tests can still be useless. But at least it has potential.)

I’ve written a lot of legacy code over the past few years. I’ve only quite recently started unit testing routinely in new code I write, and I still need to crisp up my development practice—fewer lines of code per task, more of them demonstrably working. I might not find Feathers’ definition of legacy code entirely satisfactory as a cultural one, but it’s a highly useful stimulus.

The Great North Run

Following my first attempt at competitive (well, timed anyway) running, the Marathon of the North in Sunderland in May, last weekend I ran in the Great North Run.

This was described in Wikipedia as the world’s largest half-marathon until a recent edit demoted it to second behind Göteborg. Still, it’s big. I’d heard some of the numbers, but I was still boggled by the scale of the thing, especially after the small inaugural Sunderland marathon.

I got to the starting area very early, on a coach transfer, and set out to walk from the start line back to the end of the starting pens. It took about quarter of an hour. Then when it came to start the race itself, by the time I passed the start line—having shuffled with the crowd of other runners up from my zone—the clock was already over 27 minutes!

(I didn’t understand the zoning system at all, but it’s presumably based on previous race times. I’d never run a timed race of any distance when I entered this one so I was placed quite far back.)

It was pretty much impossible to run at a constant speed in a straight line for more than a few seconds during the race, because of the crowds—right up to the finishing straight I was having to leap into gaps and up onto kerbs and verges, to avoid having to slow down and risk my legs turning to jelly before I could get started up again.

Fortunately, I’m quite keen on messing about like that.

And the weather was good: it rained.  I like that too.

I finished in one hour 47 minutes (and 50 secs) which is a bit faster than I’d expected.

All in all I was most taken by the half-marathon distance—a proper run without the slightly insane nature of a marathon. Looking forward to the Bath half in March.