When I started in software engineering, I thought it was all about languages, frameworks and folders names, actually I remember when my biggest concern was about naming variables in a clear and understandable way — and don't get me wrong, those kind of stuff are really big important things to think, reflect and learn about, but if there's something that we must really care about when working on a project is picking a good Architecture, because that’s where the flexibility to make new changes easily lies. So in this article I'll try to teach you about how to stop your business logic from dating your database.
What Do We Mean by Architecture?
In the world of Software Engineering, architecture is a set of high‑level decisions and constraints that shape how a system is built and how it evolves over time, and this involves thinking about how responsibilities are divided, or how components depend on each other, or even how easy it's to change something — and how much expensive it might be.
A good architecture protects the parts of the system that change the least — like business rules — from the parts that change the most — like infrastructure and delivery mechanisms.
Dirty Architecture?
There's not such official term like a "dirty architecture" or "non-clean architecture", however there are signals for a bad architecture:
Business logic depends on frameworks. It's not a common thing but just for a second think about what happens if you decide to decouple your framework from your project.
Business logic depends on the database. Have you ever thought about using a different database for your project? How much does it cost? And I'm not taking about switching the database driver for the ORM, I'm talking about replacing the whole storage layer. Don't get mad, but if switching from your SQL database to a file in the filesystem makes you to re-write the entire app, your architecture s*cks.
Changing the transport is expensive. You have a REST API and your team decides to switch to gRPC or GraphQL. Would that be an easy task, or would you need to start the project from scratch.
Clean Architecture
What does exist is the term "Clean Architecture", introduced by Robert C. Martin (uncle Bob). You may know him for his books, or maybe for his rants on X. He first wrote about Clean Architecture in a 2012 blog post, and later in 2017 we got a book about the same.
The signals of a Clean Architecture are clear:
- Business rules are independent of frameworks.
- Business rules are independent of databases.
- The system can evolve without rewriting core logic.
As for the rules, the Clean Architecture only has one rule: source code dependencies must point inward, toward the business rules.
Original diagram by Robert C. Martin in his blog, used for educational purposes.
You might be wondering, "If it works, why do I need Clean Architecture?" I asked myself the same question before rewriting an entire service using a "clean" approach. The answer is simple: software rarely stays "done". A system can work perfectly today and still fail the business tomorrow—not because it crashes, but because it becomes too expensive to change.
The key insight that I learned from Clean Architecture book is to compare the extremes: a program that works but is effectively unchangeable becomes useless the moment requirements evolve, while a program that is easy to change can be made to work and kept working as the business learns.
In practice, systems don’t become literally unchangeable, they become economically unchangeable when the cost of change exceeds the value. Clean Architecture is a practical way to stay on the “easy to change” side of that trade‑off by keeping dependencies pointed inward (toward business rules) and treating frameworks, databases, and delivery mechanisms as replaceable details.
Hexagonal Architecture
I could say this is one of the most famous Clean Architectures nowadays, the Hexagonal Architecture or better known as Ports and Adapters, introduced by Alistair Cockburn on his blog in 2005.
It's known as Ports and Adapter because "Ports" are the abstract interfaces that define the protocols and interactions your application exposes or requires according to the business rules, and "Adapters" are the concrete implementations of those ports for specific technologies like HTTP handlers, databases, queues. And the reason because it's also called "Hexagonal Architecture" is not because it's required to have six things; it’s because the hexagon shape shows how multiple interfaces connect with the outside world.
This makes input mechanisms (HTTP, CLI, gRPC) and output mechanisms (Postgres, Redis, APIs) interchangeable without changing the core logic. Think about your project as a Lego system.
The goal of the image above is to highlight that the boundary of the application is what matters: inside are the business rules and use cases, and outside are all the ways the application connects with the world.
You may have also noticed in the image above the distinction between a "Driving side" and a "Driven side". This concept comes from Cockburn's original Ports & Adapters (Hexagonal) model. The driving (primary) side consists of actors and adapters that initiate actions into the application core — such as user interfaces, HTTP/gRPC requests, CLI commands, or test scripts. The driven (secondary) side consists of actors and adapters that the application itself drives in order to fulfill its work — such as databases, external services, or other systems. The distinction is based on who triggers the interaction: driving adapters call into the core through its ports, while driven adapters implement the ports that the core calls to interact with external technology. This separation helps ensure that the business logic remains isolated from and independent of specific technologies or protocols.
In conclusion, if your architecture allows you to refactor code and change transport mechanisms, databases, or queues as easily as swapping your car’s wheels, then you’ve reached the Valhalla of software engineering — a place where change is expected, not feared.


Top comments (0)