Spaghetti code is a term developers use to describe code that’s messy, tangled, and hard to follow. It often grows without structure and becomes a pain to work with—especially when you're trying to add new features or fix bugs.
What causes spaghetti code?
- Large classes and methods
- Multiple responsibilities in one class
- Using the
goto
keyword - Bad naming
- Magic numbers
- Code repetition
An example
public class OrderProcessor
{
public void ProcessOrder()
{
Console.WriteLine("Enter product ID:");
int productId = int.Parse(Console.ReadLine());
Console.WriteLine("Enter quantity:");
int quantity = int.Parse(Console.ReadLine());
double price = 0;
if (productId == 1)
price = 10.99;
else if (productId == 2)
price = 15.49;
else if (productId == 3)
price = 5.25;
double total = price * quantity;
Console.WriteLine("Do you want express shipping? (y/n)");
string shipping = Console.ReadLine();
if (shipping == "y")
{
total += 5.0;
}
Console.WriteLine("Order Summary:");
Console.WriteLine("Product ID: " + productId);
Console.WriteLine("Quantity: " + quantity);
Console.WriteLine("Total Price: $" + total);
Console.WriteLine("Saving order...");
Console.WriteLine("Order saved.");
}
}
What’s wrong here?
- One class is doing everything
- Magic numbers everywhere
- No reuse or structure
- Not easy to test or maintain
A cleaner, more structured version
public class ProductService
{
public double GetPrice(int productId)
{
return productId switch
{
1 => 10.99,
2 => 15.49,
3 => 5.25,
_ => throw new ArgumentException("Invalid product ID")
};
}
}
public class Order
{
public int ProductId { get; set; }
public int Quantity { get; set; }
public bool ExpressShipping { get; set; }
public double CalculateTotal(double pricePerItem)
{
double total = pricePerItem * Quantity;
if (ExpressShipping)
{
total += 5.0;
}
return total;
}
}
public class OrderUI
{
private readonly ProductService _productService = new();
public void Run()
{
var order = new Order();
Console.WriteLine("Enter product ID:");
order.ProductId = int.Parse(Console.ReadLine());
Console.WriteLine("Enter quantity:");
order.Quantity = int.Parse(Console.ReadLine());
Console.WriteLine("Do you want express shipping? (y/n)");
order.ExpressShipping = Console.ReadLine()?.ToLower() == "y";
double price = _productService.GetPrice(order.ProductId);
double total = order.CalculateTotal(price);
Console.WriteLine($"
Order Summary:");
Console.WriteLine($"Product ID: {order.ProductId}");
Console.WriteLine($"Quantity: {order.Quantity}");
Console.WriteLine($"Total Price: ${total}");
Console.WriteLine("Saving order...");
Console.WriteLine("Order saved.");
}
}
Why this is better
- Each class handles one job
- It’s easier to follow and test
- We can reuse the logic later
Other code smells
- Ravioli code – Each class is clean, but there are so many tiny parts that the overall structure gets confusing.
- Lasagna code – Too many tightly coupled layers. Changing one breaks everything else.
Question - How do you avoid writing messy, tangled, and hard to follow code?
Top comments (0)