Tackling badly-written software

For too long I had grappled with this codebase - tangled, confusing, complicated - and was finally able to turn it into the simple solution that it always could have been - here's how I did it!
Tackling badly-written software
March 2026

What was so bad about it?

  • Inconsistent terminology: the domain language used was not consistent across the code base. The same things were referred to by multiple different terms
  • Tangled code: hurried code edits without peer review further compounded the problem of poor terminology and led to duplicated code, almost-duplicated code (code that was so similar it could have been collapsed together with some switches, but it wasn't, hugely increasing the bug space, and causing drift).
  • The bigger picture: it was difficult to understand where this software sat in the bigger picture of the organisation we were working for - we had failed to extract the full context from the client.
  • Passed around lots of hands: not necessarily a problem if all of the above points have been suitably met - but learnings, context and terminology were not adequately handed over as the project changed hands.
  • Lack of adequate review: careful and challenging review of code changes was just not happening - reasons for this are explored later
  • Poor data model: further to the problems with the domain model, the data model and the design of the database was not optimal - foreign key constraints were missing, columns poorly named.
  • Untestable: the structure of the code made unit or functional testing very difficult. Classes were long, rambling with many dependencies and had no clear purpose. Data-loading logic was mixed up with domain-specific logic, meaning that trying to target tests at the 'important stuff' was borderline impossible!
  • Intertwined with other products: this project was also a dependency of another business-critical tool, making changes difficult to co-ordinate and justify.

What did I do about it?

To me, the most important things in software engineering are:

  • Using the correct domain language
  • Testability
  • Data model is king

Therefore, I took the following approach:

  • Held a clarification session with the client to talk through the problems - from both a product and a technical perspective - and come up with a plan
  • Started a glossary, ensuring that terminology could be better shared between team members present and future
  • Better database object naming - if a table holds a list of apples, call it Apples - it makes reasoning about future bugs far easier!
  • Strangle out the old code. Don't try to salvage the old code in-place - it's the road to madness, as fundamentally its foundations are bad. Create a new, separate API for the new, clean code - fully tested, well separated and very understandable. But - critically - leave the old API in place, and as API endpoints are replaced, forward requests from the old system to the new system, until the old system is fully 'strangled out' - this is known as the Strangler Fig approach.
  • Don't over-engineer. As software engineers we can get into habits - introducing high levels of abstraction, very high efficiency, zero code duplication - but often fail to realise that sometimes this is just not necessary, takes a load of time and clouds the software's true intentions. Why optimise your system for 1,000,000 requests per second if it's only used once a week by 3 people?
  • Be right, not fast - this is the time to be calm, take time and model the right solution - this situation was partly created by trying to be fast in the first place!

Going forwards

Time will tell whether this has been the right approach - but I'm confident. This solution is now more:

  • Testable
  • Understandable
  • Accurate
  • Maintainable

So we're now standing on good foundations!

Read next

Abstract illustration of a fast simple hosting setup
Mar 2026

How I manage content on this website

Learn how this blog site is put together - with minimal dependencies and bloat

Read post →
VW Golf dashboard with a start-stop system failure warning light illuminated
Apr 2026

Troubleshooting the start-stop system failure on my VW Golf - Part 1

Usually I write these blog posts after I've fixed the problem - but this time I'm writing it as I go. Join me as I gather information and build a list of ideas.

Read post →
A smartphone camera lens surrounded by abstract binary data streams and TIFF file grid patterns
Mar 2026

Generating TIFF files on an Android device

No library was up to the job, so I read the spec and wrote my own TIFF encoder.

Read post →