Simplifying Hexagonal Architecture: Using Capabilities and Requirements for Better Code
Tags: architecture
Published: 2024-05-03 06:30:00

Imagine walking into a new house – clothes scattered everywhere, dishes piled high! Finding anything would be a nightmare. This is what a poorly organized codebase feels like for programmers. Every coding project, big or small (websites, phone apps, etc.), needs a well-defined folder structure.

This article explores hexagonal architecture, a powerful approach to organize code, and how it can be adapted to create a clear and maintainable folder system for your software development projects.

## Hexagonal Architecture: Simplified Overview

Hexagonal architecture, also known as ports and adapters architecture, is a favored pattern in software design for its simplicity and effectiveness:
- **The Core:** Imagine it as the heart of your program, housing essential logic without concern for external factors.
- **Ports:** These are interfaces surrounding the core, specifying data requirements and how results are delivered.    
- **Pluggable Adapters:** Specialized tools connecting to ports, handling interactions with databases, UIs, or external systems.

![Example of hexagonal architecture from Wikipedia](https://upload.wikimedia.org/wikipedia/commons/7/75/Hexagonal_Architecture.svg)

This separation enables:
- **Easy Adapter Swapping:** Switching between different technologies is seamless; just create a new adapter without altering core logic.
- **Focus on Business Logic:** Developers concentrate solely on core functionality without distractions from implementation details.
- **Improved Testability:** Core logic can be tested independently, simplifying unit testing processes.


## Domain Concepts and New Hexagonal Architecture Approach

In software development, the domains represent the core functionalities of an application, free from technical details. For instance, in a restaurant reservation system, terms like "Reservation," "Customer," and "Table" define three domains.

I want to introduce the concepts of "Capabilities" and "Requirements" I took from Thomas Bub and his article [How to do the package structure in a Ports and Adapters architecture](https://tbuss.de/posts/2023/9-how-to-do-the-package-structure-in-a-ports-and-adapter-architecture/):

- **Capabilities:** These are the services a domain offers to others, such as "Retrieve Customer" or "Create Customer."
- **Requirements:** These are the functionalities a domain needs from others to fulfill its responsibilities. For example, the "Reservation" domain may require the "Customer Lookup" capability from the "Customer" domain.

![Capabilities and Requirements Folder Structure Example](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nwyh2mci6eq5vf485kut.png)

By employing these terms, the folder structure enhances clarity and maintainability:
- **Improved Readability:** Developers can understand specific domain interactions easily.   
- **Enhanced Maintainability:** Changes to a domain's capabilities or requirements are identifiable and manageable.

This approach streamlines communication and reinforces the clean structure of hexagonal architecture.

## Benefits and Drawbacks of Shifting Terminology in Hexagonal Architecture

Shifting from "ports" and "adapters" to "capabilities" and "requirements" in hexagonal architecture brings several benefits:
- **Improved Understanding:** Using terms like "capabilities" and "requirements" makes code self-documenting. Developers easily grasp what functionalities each domain offers and what services it needs, enhancing overall comprehension.
- **Enhanced Readability:** By replacing generic terms with domain-specific ones, such as "Retrieve Customer" or "Customer Lookup," the code becomes more readable and understandable, improving long-term maintainability.
- **Decoupling of Technologies:** Reinforcing the separation between core logic and external concerns, this shift focuses on functionalities rather than technologies. It allows for easier technology swaps without affecting core functionalities.
- **Encapsulation of Functionalities:** Each domain becomes a well-defined unit with clear boundaries, reducing the risk of ripple effects through the entire application and enhancing maintainability.

However, there are some drawbacks to consider:
- **Increased Code Verbosity:** Descriptive names like "CustomerRetrievalCapability" may increase code verbosity slightly. Yet, the gain in clarity usually outweighs this.
- **Learning Curve:** Adopting this naming convention may pose a learning curve for developers unfamiliar with hexagonal architecture. However, the long-term benefits in readability and maintainability justify the initial investment.


## Conclusion

While using capabilities and requirements encourages domain-specific language, the ability to think abstractly remains crucial. Developers still need to understand the underlying principles of hexagonal architecture and how different domains interact. This allows them to design effective capabilities and requirements that promote loose coupling and maintainability.

Overall, the advantages of using "capabilities" and "requirements" in hexagonal architecture often outweigh the potential drawbacks. With clear communication and a focus on intent, developers can leverage this approach to create well-structured, maintainable, and easier-to-understand software projects.


## References

- _How to do the package structure in a Ports and Adapters architecture: [https://tbuss.de/posts/2023/9-how-to-do-the-package-structure-in-a-ports-and-adapter-architecture/](https://tbuss.de/posts/2023/9-how-to-do-the-package-structure-in-a-ports-and-adapter-architecture/)_
- *Hexagonal architecture (software): [https://en.wikipedia.org/wiki/Hexagonal_architecture_%28software%29](https://en.wikipedia.org/wiki/Hexagonal_architecture_%28software%29)*