Scaleyourapp
Software Design

Spaghetti code explained with a real-world use case

What is the Spaghetti code?

Spaghetti code also referred to as the big ball of mud, is code without a definite structure and resembles spaghetti. This form of code is tightly coupled, hard to maintain, and refactor and a nightmare for the devs working on it. 

Spaghetti code is a software design anti-pattern found in applications where the delivery speed of application features is prioritized over code quality resulting in massive technical debt. 

Let’s understand this with the help of a real-world use case.


Spaghetti code use case – Online food delivery service

Imagine an online food delivery service comprising multiple business functionalities such as taking orders, routing those orders to the right restaurant and the delivery person, accepting payments, user memberships, inventory, and so on. 

The Spaghetti code for this application will have total discard for the software design principles and would have all the features coded tightly coupled with each other. The code will have no layers (controller, service, business, DAO, etc.), no use of SOLID OOP principles, no use of interfaces and modular design; rather, everything coded together like a big ball of mud. 

With an application having Spaghetti code, it would be overly painful to add new features since—first, the devs would have to figure out the code flow for a certain feature and then make the changes hoping the new code doesn’t break the existing functionality. 

This may result in an endless cycle of bug fixing with the spawning of new bugs due to the former bugs being fixed, which will eventually throw a wrench into the gears resulting in financial loss.


Why do we end up with the Spaghetti code?

There are several reasons, stated below, behind dev teams ending up with Spaghetti code:


What can we do to avoid the Spaghetti code?

Use a layered architecture as opposed to stuffing everything in a single layer. 

Layered Architecture 

In most enterprise projects, you’ll find code split up into layers like the controller, service and data access layers. We can always add more layers to our code based on the requirements and the complexity of the project. 

When it comes to Java Spring enterprise projects, layered architecture is the defacto pattern that is leveraged. 

In the layered architecture, also known as the lasagna code, every layer has its specific role; for instance, the controllers will handle requests specific to a certain business feature or domain, the service layer will execute the business logic, the data access layer will communicate with the database and so on. They communicate with each other via interfaces to keep things loosely coupled and abstracted.

With this, specific layers, such as the service layer, wouldn’t worry about what is going on in the controller or the DAO layer. It just does its job, that is, executing business logic and passing the data across the DAO and the controller. Having a layered architecture helps implement the separation of concerns. 

With this architecture, a change in a certain layer of the code won’t impact other layers much. The layers are isolated. This facilitates easy development and testing, keeping the code maintainable and extendable.

Hopping back to our online food delivery service use case, we will have the business functionalities like order management, order routing, payment, user memberships, inventory, etc., implemented as verticals in a layered architecture as opposed to having all these in a single layer in Spaghetti code.


End-to-end request flow in a layered architecture

Now, with the layered architecture, when a user searches for food items in their app, the request is handled by the inventory controller and then moves to inventory service and the inventory DAO and back. 

When they book an order, the request is handled by the order management (controller, service, DAO) flow. And when they pay for the order, the request is handled by the payment flow and so on. 

So, you see, the business functionalities are spread across the layers vertically. Anytime we need to update any business feature, we can do it without nudging the code of other business features much.

Why do I say much?

Because however, the business functionalities are separated in layers, they are not completely isolated. There is cross-communication between them, and in complex projects, this might again lead the code to become a big ball of mud/Spaghetti.

To tackle this, we either move to microservices or implement a modular monolith architecture. I’ve discussed that in a separate article here.

If you wish to master the fundamentals of web architecture and learn to design large-scale distributed systems starting right from zero, check out the Zero to Software Architect learning track that I’ve written.


Besides implementing a layered architecture, there are a few other ways to avoid ending up with the Spaghetti code

Recommended reads: Monolithic architecture explained in simple words | Web application architecture explained with a real-world example

Folks, this is it. If you found the content helpful, consider sharing it with your network for better reach. Check out the Zero to Software Architect learning track. I wish I had a similar learning product in the initial years of my career. 

I am Shivang. You can catch me on LinkedIn here. I’ll see you in the next write-up. Until then, Cheers!

Related posts

Distributed Systems and Scalability Feed #1 – Heroku Client Rate Throttling, Tail Latency and more

Shivang
4 years ago

Monzo Architecture – An Insight Into the Backend Infrastructure of a Modern Digital Bank

Shivang
5 years ago

Parallel Processing: How Modern Cloud Servers Leverage Different System Architectures to Optimize Parallel Compute

Shivang
8 months ago
Exit mobile version