Spaghetti Code is a programming anti-pattern in which code becomes almost impossible to maintain or change due to ongoing changes, interactivity between modules, or general untidyness. Usually this does not happen all at once; rather, it happens slowly over a long period, and only by coming back later do you notice the mess.
Spaghetti Code is the granddaddy of all programming anti-patterns; it's been around forever, everyone knows what it means, but no one agrees on a universal definition of it. We do, however, agree on the solution: refactoring. But what's better than having a solution and using it? Having a solution, and not needing to use it.
- Name: Spaghetti Code
- Summary: Code which is so difficult to read or change that it becomes nearly impossible to maintain.
- Type: Programming
- Common?: Mamma mia!
Give Me an Example!
Hoo boy. I cannot count the number of times I've worked on something that could be called spaghetti code. I'm probably working on it right now, in some form; you cannot tell if code is spaghetti code until you're nearly done working with it.
The worst time I had working with spaghetti code was at a short-lived job right before my current one (which I wrote about previously in "Be Like Us or Else"). At that place, we maintained desktop-based insurance systems for local agents, ones that would allow said agents to come up with home insurance quotes based on things like home size, amenities, and potentially-dangerous features (e.g. a pool or trampoline).
I was charged with fixing what appeared to be a relatively simple bug in this insurance quote application. The quote wasn't correctly including the fees that having a trampoline at a home would normally incur. Simple, right?
Except... the calculations were off. The code which calculated how much each potentially-dangerous feature would cost the homeowner in premiums were totally intertwined with the code that managed which features were selected. In order to change the calculations I ended up changing around 10 files and 60 lines of code for what should have been a single one-line fix. Worse, these changes I made cause two other bugs, resulting in a Hydra-like farce of bug hunting. It was madness.
And that's just the most memorable encounter I've had with this anti-pattern. I've worked on spaghetti code hundreds of times. In fact, I'd be willing to call it the most common of all the anti-patterns in this series, or at the very least a contender for such a title.
Which should make it easy to solve, right?
Strategies to Solve
The problem with spaghetti code, as I mentioned earlier, is that everyone knows what it is but no two people have the same definition. So if no one agrees, how do we fix it?
First, let's dispel the notion that spaghetti code is anything but an umbrella term for "code that is difficult to maintain." That's exactly what spaghetti code is. But since "difficult to maintain" is relative, what exactly do we do about it?
First and most importantly, we enforce team programming standards. Things like coherent naming, proper structure, and consistent code reviews go the furthest in reducing spaghetti code. But if those aren't already in place, then there's only one solution left to us: refactoring.
There's lots of good resources on the internet for refactoring, so I won't go over them all here. Rather, I'll point out the two strategies that worked best for me when dealing with spaghetti code.
WHO MADE THIS MESS?! (Image found on Flickr, used under license.)
- The top-down approach. Subdivide the problem, breaking it into little Lego-sized pieces that can be implemented independently. You can then build the solution up from the individual pieces. However, this takes time, and deep knowledge of a system. But debugging code is much harder than writing it, so this time might be a good investment.
- The bottom-up approach. As you make changes to this code base, also include small changes toward de-spaghettifying the code. For example, rename classes and properties to match team standards, split objects out into their own dedicated files and namespaces, or separate the business logic from the data logic or other layers. By approaching the problem this way, you can make the exact kind of incremental changes that result in spaghetti code, but in reverse, and given enough time this can result in a much more maintainable system.
Either of these approaches, given the appropriate time investment, will result in much cleaner, less spaghettified code. Choose whichever suits your individual situation the best.
Spaghetti Code is code that is difficult to maintain due to excessive inter-dependency, a lack of documentation or structure, or simple haste. Refactoring is the best fix, but an ounce of prevention is worth a pound of cure, and so proper naming, structure, and reviews for team standards will prevent your code from becoming spaghettified.
When did you last deal with spaghetti code? Can you top my story from earlier? I want to know about your experiences. Share in the comments! Or else head on back to the series index page to see some more anti-patterns.