Skip to content

Instantly share code, notes, and snippets.

Forked from corlaez/
Created December 9, 2022 03:44
Show Gist options
  • Save thangchung/1cf8ebb9dd72c96be6ed948b27360502 to your computer and use it in GitHub Desktop.
Save thangchung/1cf8ebb9dd72c96be6ed948b27360502 to your computer and use it in GitHub Desktop.
Hexagonal Architecture and Modular Implementation

Hexagonal Architecture

Conceptualized by Alistair Cockburn. Also known as "Ports and Adapters".

In a nutshell:

Application Driver -> Primary Adapter -> Primary Port -> Use Case -> Secondary Port -> Secondary Adapter -> External System/Side Effect


Use Cases

They define the business rules and they should not depend on code related on how the system communicates with the outside world. Throught the use of Ports and Adapters the Use Cases can be reliably tested and change mainly if the business rules change


They expose the ways in which the use cases can be reached (primary) or reach to (secondary) to the outside world. They are technology agnostic.



They deal with with side effects such as: communication outside of the system, random generation, current time, etc.


Port and Adapter Implementation


Hexagonal Architecture - Modular Implementation

Based on talks by Jakub Nabrdalik.


Modules Project Structure

There are multiple ways to implement the ideas of this architecture this is by no means the only one. This implementation is modular and as such it can scale to implement a modular monolith (modulith).

  • Each module is an Hexagonal Architecture "Hexagon" (It has ports, adapters and use cases).
  • There is a heavy use of package-private and a minimal, thoughtful use of public.
  • Subjects Under Test in your unit tests are Primary adapters (mocking the Primary Port), the DTOs (if needed) and the Primary Port (using fakes and mocking other modules)
  • Each module has a Configuration file that assembles the classes together for production and testing use.

Additional notes on implementation

  • In the following example I decided to move customerconsole package outside of the customer module because it required it's own module configuration. However, there is nothing stopping the package to remain as a folder inside of

  • Depending on the library choice or code implementation, your primary adapters may need to be public. Jakub's package-private controllers are possible because he uses the Spring framework.

  • Primary adapters expose an API to an external agent so you may want to treat them as a public API regardless of the access modifier used for the class


Module configuration and it's relationship with mock testing:

Useful Links:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment