“Build One to Throw Away (You will anyway)”

When I read that line from The Pragmatic Programmer in the 2000s, it shocked me.

What do you mean throw software away? I just got it working!!

20 years after its initial publication, we still are adverse to throwing code away.


Some examples of this:

  • Your team uses a GenericRepository<T> that somewhat works. It works for your entities that have the same ways to get them (GetById, GetAll, Find), but it fails for when you need child discrete entities (think of getting all orders in the system for a report; or all orders that contain a certain product) without getting their parent entity (in this case, the “Customer”), and then you have this weird thing where you try to add another method to the GenericRepository to work around this because we’ve invested in the GenericRepository<T> pattern. (This is a real example I’ve encountered multiple places)
  • A developer comes up with a new way of doing something in your system that contravenes your established convention, but is more readable and maintainable. People on the team who are afraid of change start to bring up lots of reasons why you can’t possibly do it that way, and that this change should be ‘researched more’ (note: If you’re asking someone to ‘do more research’ without a specific deliverable and a specific question you want answered, you’re really just softly scuttling the idea. Also, asking someone to ‘do more research’ when they did the research and your question doesn’t have the answer you want is also scuttling the idea).
  • About six months into your project, you realize that a relational database wasn’t the best choice of data store for your project. Or that ArangoDB is just too niche to get support for, and instead of saying “We need to stop now, our foundation was for a house and we’re building an office building”, you plod on, introducing ever more complicated caching and retrieval mechanisms to work around the database.

I could go on. Over my career, I’ve heard and experienced stories of this that all come back to the same general idea:

Once it works, we don’t want to change it.

or put another way:

We get invested in how we solve problems, and don’t want to learn new things.

All of this is normal, and it the prime reason why we don’t change precisely when we need to. There is inertia to the old ways of thinking and doing business.

But remember the second part of the quote: You will [throw it away] anyway.

I suppose on a long enough timescale that’s a tautology, so I’ll focus on the short term.

What modules have you rewritten over the past year? Why did you rewrite them?

What changes did you make that your architecture hadn’t accounted for? What did you do when you found this out?

There’s a saying You’ll never know less about your problem than you do right now.

Tomorrow you’ll know more than today, and so on.

If your hesitance to throw away what you built is that you’ll lose work; you’re right. You’ll lose work created with less understanding than you have right now.

You’ll lose work created (sometimes) on false premises.

The upside to throwing away work is that it gives you room to correct those false premises.

The upside to using TDD is that while you may throw away the work, you’re generally not throwing away the customer’s view into your world; allowing you to correct your thinking and verifying it’s correct without disrupting your customer.

That’s very powerful, and a powerful reason to adopt TDD. You’re going to throw away your work, would you rather throw it away and replace it with confidence? Or without confidence?

Leave a Reply