▶️ The Legacy Code Survival Guide: Add Features Without Fear


Hello Reader 👋

I hope you are doing well today!

A few months ago, Steven Diamante delivered a talk on Legacy Code at the Seattle Crafter Meetup. I've recently watched it and, although I'm familiar with these techniques, I thought they were particularly well articulated.

I also enjoyed the heroic-fantasy, D&D vibe that transpires throughout the presentation.

Honestly, the talk is really good! It's a mix of theory, mindset, and concrete implementation 👌

video preview

The recording may feel a bit long, but it's worth it.

Here's my breakdown of interesting sections, if that helps:

  • 00:20 - Introduction
  • 03:23 - Why changing legacy code feels risky? Legacy Code is profitable software that I'm afraid to change.
  • 10:13 - The plan: explore the code, break dependencies, build safety nets, refactor carefully, and add features. Having a short feedback loop makes code easier to change.
  • 13:55 - Context: the specs to implement and the existing app. Exploring the code, see what we have. I like how realistic this example is.
  • 16:43 - Setting up a first test. By doing this, we start learning about the problems and difficulties of this codebase. We are writing a "characterization" test: the goal is to capture what the system currently does. Not what it should do. I wrote about this in Approval Tests.
  • 20:45 - Break dependencies. Steven mentions different techniques, such as Subclass & Override, Peel & Slice, and Dependency Injection in general. He also shows how he leans on his IDE to automate refactorings. Without tests, this is the safest approach to modifying code. These refactorings will help him break the annoying dependencies, so he can set up the safety net that will allow for more ambitious refactorings later.
  • 26:50 - Build safety nets. Interesting discussion about the type of tests to write. A mistake would be to write tests that rigidify the implementation details (what most people would call "unit tests"). Instead, we want to cover the behavior of the system at a reasonable distance, so the tests won't break when we refactor the design. We are relying on Approval Tests again here.
  • 39:50 - Anecdote: an Approval Testing story gone wrong. A good reminder that, even with the right tools and techniques, working with Legacy Code can be tricky since you often are not alone in this. In particular, it's common for developers to start ignoring Approval Tests failures since they would break any time you need to change the code's behavior. If they are not trivial to read, people stop reading them. You end up with an illusion of safety: you have tests, but you can't tell noise from signal.
  • 42:03 - Refactoring the code, carefully. Go for the low-hanging fruit, rename things, spot and remove duplication, extract code and concepts (e.g., Value Objects). In particular, do the refactorings that will enable the features you need to implement.
  • 01:04:17 - Adding the new feature. Leaning on the shoulders of previous tests, refactorings, and learnings, we can now implement the specs efficiently and safely.
  • 01:12:18 - Common code smells. Steven goes through typical issues you will find in legacy codebases.
  • 01:13:15 - What about GenAI? It's a great tool to support you, but you can't just delegate the work. Coding agents are not ready for dealing with Legacy code in autonomy. You still need to know the techniques, the vocabulary, so you can guide the agent. That being said, LLMs can help you grok the codebase faster.
  • 01:17:36 - Key takeaways. A good recap and mention of helpful techniques. Most of these I've covered in my book "Legacy Code: First Aid Kit" 😃

Finally, you can dig into the source code to follow along with the presentation: https://github.com/SDiamante13/loan-management-service

I hope this breakdown will help you dig into this great presentation. There is a lot to learn from seeing Steven go through a realistic example of legacy code. With a bit of practice, you can do that too 😉

Until next time, take care!

Understand Legacy Code

Piles of Tech Debt, no tests, no docs, short deadlines… But you are not alone! Join me and get regular tips, tricks, and experiments to turn unfriendly codebases into insightful ones 💡

Read more from Understand Legacy Code

Hello Reader 👋 I hope you are doing well today! I recently finished reading “Refactoring at Scale” by Maude Lemaire, while on a nice family trip to Toronto, Canada 🍁 Honestly, I found it quite good. It's packed with interesting insights and good advice built from concrete real-life experiences. It has become one of the few books I would recommend to someone dealing with a huge codebase, dozens of engineers constantly molding it, and pressure to keep delivering business value to customers....

Hello Reader 👋 I hope you are doing well today! Do you often find yourself fighting with the intricacies of legacy code or navigating through convoluted programming structures? In his popular “Refactoring” book, Martin Fowler collects an impressive catalog of moves that can transform the way you approach code maintenance and evolution. If you haven’t read it and are unsure what to expect, I’ve written down a high-level summary of what you will find here. Hopefully, that gives you a better...

Hello Reader 👋 I hope you are doing well today! If you had a magic wand, what would you do with the tangled legacy codebase you are dealing with? For many developers, the answer will go along the lines of: Kill it with Fire!!1!Let’s rewrite the whole thing on a modern stack. Hopefully, Marianne Bellotti, the author of the book with such a provocative title, has better options for you. I've read it cover to cover and I will share with you my personal highlights here. P.S. here’s a shareable...