A good development team has no heroes.

There are three common "heroic" feats in software development:

  • Hacking in features in a fraction of the time it should have taken.
  • Pulling all-night hacking sessions to get a delayed project out the door.
  • Fixing a hack that exploded in production and took everything down.

Good teams don't do these things. Good teams produce realistic, defensible estimates that stop the project being delayed in the first place. They don't release fragile code to production. And the thing people who haven't worked in such an environment find hard to believe: they're still just as fast, if not faster. When Uncle Bob says, "the only way to go fast is to go well", he's not kidding.

Let me give you an example from my experience. I once took over a project that was the result of about a year of extended heroics: late night hacking session on top of late night hacking session, onion-like layers of convoluted production fixes that never touched the underlying problem, and a record for delivery that had become atrocious. Despite claims of development being lightning fast using the quickest and dirtiest fixes possible, it was excruciatingly slow. The team were suffocating under the weight of their own heroics; even the most minor change was estimated as requiring weeks of additional work to tackle the technical debt, and as a result inevitably became yet another last-minute hack.

What I did was to spend a couple of weeks sitting with one other developer, going through and rationalising the code. (Thankfully, after months of strife it was easy to get management to support, "just two people for two weeks to make things much better"). We started out by writing tests for the existing behaviour, and when the test criteria didn't make any sense we went back to the business requirements to write a new test that did. Then we hit the code. Most of this ended up being a code deletion exercise; correct a wrong basic assumption or a badly-modeled state change, then delete the dozen or so hacks that had been added upstream to deal with that problem. At the end, we had a much cleaner code base with a clear state model, no chain of hacks setting or unsetting the same value, and no needless duplication between different layers of the application.

The consequence was that by breaking with the existing ethos of high-profile heroism and putting in some solid, undramatic groundwork, we had started to go well. Which meant we could go fast. Rather than promising something in three weeks, delivering it late after a week of late nights, then doing an emergency fix after finding a certain result was calculated in the front end rather than the back end only in certain specific circumstances... we'd promise it in two weeks, deliver it in two weeks, and release with no bug so important it couldn't wait for the next version. Not only that, but in striving for generic, clean code we'd make subsequent development even faster. As a result, the team got to leave the office on time and didn't have to be paged in the middle of the night: it didn't do grandstanding theatrics and it didn't have any heroes.

But that, as I say, is a good thing.