How to fix your spaghetti code (and avoid it in the first place)

February 25, 2022

Software is said to be written with “Spaghetti Code” when the software is difficult to maintain or extend. Spaghetti code is hard to understand what it’s doing, and has twisting and winding code paths that are difficult to follow (like a big bowl of spaghetti). Software with Spaghetti code will take longer to add new functionality and will often lead to strange bugs. Plainly put, Spaghetti code costs your company time and money.

Avoid with SOLID Principles

You can avoid spaghetti code by implementing and adhering to basic design patterns within your codebase. For Object-Oriented (OO) languages (Java, C#, Typescript, etc), a good way to avoid spaghetti code is by utilizing the SOLID principles of OO design. For those not familiar, the principles are:

1. Single Responsibility
  • Every component has only one reason to be changed therefore one responsibility
2. Open-closed  
  1. Components are open for extension but closed for modification
3. Liskov’s substitution
  1. Every subclass or derived class should be substitutable for their base or parent class
4. Interface segregation
  1. A client should never be forced to depend an interface or method they don’t use
5. Dependency inversion
  • High-level modules should not depend on low-level modules. Both should depend on abstractions (e.g., interfaces)
  • Abstractions should not depend on details. Details (concrete implementations) should depend on abstractions

Solutions to fix existing spaghetti code

We, as developers, have all experienced spaghetti code in our careers (and if you haven’t yet, you will). We have all either inherited it from another developer(s) and, yes, we’ve all written spaghetti code at some point in our careers. So what do we do when we have a big bowl of spaghetti on our plate? Well don’t panic, we can fix it! Follow these steps:

1. Take an iterative approach

Don’t try and rewrite it all at once. Unless you can completely throw away the code-based and rewrite it, it’s often best to refactor in small chunks. Start with parts of the codebase you have to work with the most. This will offer the most “bang for your buck”.

2. Write tests

In order to untangle a messy codebase is to make sure we can make changes and refactors safely. However, often times a messy codebase lacks good (or any) test cases. Due to the nature of spaghetti code, it’s also often difficult to introduce unit tests to begin with. In these situations, it’s best to write a handful integration tests that exercise the part of the codebase you’re looking to change. Start by writing tests against the existing code base that all pass. Then, start to refactor bits of the code you’ve identified to rewrite. Your code should be more testable, so be sure to be writing unit tests along the way! Once your code is refactored, and your unit tests are in place, you can remove any unnecessary integration tests!

3. Introduce interfaces

Spaghetti code is very tightly coupled by its nature. There are lots of “if this, do that; if this other thing, do something else. A common way to reduce coupling is to pull out this logic and place it behind an interface. Not only will this decouple your functional code, but it will also give you a clean interface to write unit tests against.

4. Follow the scouts’ rule

“Leave the codebase cleaner than when you found it”. As you continue to grow and shape your software product, take the time to improve little pieces along the way. Make a method or variable more readable, factor out a large chunk of logic into a clearly named function, or introduce a unit test for an uncovered code path. Over time, you will find the codebase much cleaner than when you started!

In Summary

Spaghetti code is costly, but it happens. If you have inherited it or are still learning to clean it up — start small and improve over time; and if you are writing brand new stuff — be disciplined. These principles and rules exist to help code be written in more maintainable ways that will save you time, money, and a headache in the long run.