The price of the erosion architecture or "The Good, the Bad, and the Ugly"
Tags: architecture, development
Published: 2024-03-15 02:40:24

Today, instead of diving into another technical article, I'd like to share some thoughts on architecture. This short post encapsulates ideas that have shaped my career journey.

## Let's Rock 🚀🎸
Many folks recognize the importance of having architecture.

Whenever someone mentions this idea, they often refer to Martin Fowler's article ([Is High Quality Software Worth the Cost?](https://martinfowler.com/articles/is-quality-worth-cost.html)) where he demonstrates that adding new features to high-quality code is not only easier but also cheaper (I would even say more enjoyable). Martin emphasizes that quality code adheres to certain architectural principles. 
And, of course, there's the graph that illustrates this key concept.

![The graph](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u6ibpr6ezp2fscvekmuu.png)

But I've always wondered, what's the cost of having the **erosion** architecture? 
Let me break it down. **Erosion architecture** is one that doesn't match the **current** business needs and adds unnecessary complications. 

Still not clear? 🤯
Let me show you with an example:
Imagine we're building an online shop, starting with car sales. As we plan the application's architecture, we need to consider its future growth. Which direction should we anticipate?

1. If our focus remains on selling cars, we'll need more specific filters like brands, engine types, and number of wheels. Our architecture should allow for easy addition of new car characteristics.

2. Alternatively, if we plan to expand our business to include bikes, trucks, and airplanes, we won't delve as deeply into each product. Instead, we'll introduce an Enum with product types to accommodate this broader range.

### Option 1
```js
interface Repository1 {
  getCarByBrand(brand: string): Car[];
  getCarByModel(model: string): Car[];
  getCarByYear(year: number): Car[];
  getCarByColor(color: string): Car[];
  // ... other methods
}

interface Car {
  brand: string;
  model: string;
  year: number;
  color: string;
  price: number;
  owner: string;
}
```
### Option 2
```js
interface Repository2 {
  getAllVehicleTypes(): string[];
  getVehicleByType(type: string): Vehicle[];
}

interface Vehicle {
  description: string;
  price: number;
  type: string;
}
```

As you can see, both of these solutions make sense, but they represent two different axes of change. Choosing the wrong one could result in increased effort to support the architecture and add new functionality that doesn't align with it. Instead of speeding us up, the architecture could slow us down.

Unfortunately, this scenario is quite common, especially in fast growing companies. A team might choose a solution, but later, the business decides to drastically change its model. However, there isn't enough time to adapt the architecture accordingly. Whether we call it tech debt, bad quality code, or cutting corners, the result is the same: the architecture doesn't align with the **current** business needs.

Since everyone appreciates graphs, let's visualize how problematic this situation can be.


![Erosion graph](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9ujsgvq7paw9pccks9gz.png)

I still believe that having some architecture even an **erosion** one is better than having no architecture at all. Even if the architecture doesn't facilitate quick development, it at least ensures that everyone follows the same pattern.

# Conclusion 🤔

> Let it be messy but consistent