Hexagonal Architecture - BlueZone
BlueZone was created Juan Manuel Garrido de Paz to illustrate how to implement Hexagonal Architecture in Java. It shows the configurable dependency pattern.
The BlueZone project on GitHub (https://github.com/jmgarridopaz/bluezone) illustrates Hexagonal Architecture, by showing multiple Actors & Adapters, on the Driving and Driven side.
The following is a generalized visual representation:
Java Project Structure - Modular
The general structure is:
Module for Application (Hexagon)
Module for each Driving Adapter
Module for each Driven Adapter
Module for Composition Root (Startup)
For each Module, we can specify its Required Interfaces & Provided Interfaces (module-info.java), from Java 9 we can specify which packages we publish (i.e. what will be exposed to other modules).
When we structure our project, we can structure it as follows:
Application (Hexagon)
Composition Root (Configurable Dependency)
Driving Actors:
Test
Driving Adapters:
WebUI
REST API
SOAP Service
CLI
etc.
Driven Actors:
Test Double
Driven Adapters:
DB Adapter
File Adapter
Web Service Adapter
etc.
Application Structure is NOT prescribed
The structure of the Application (Hexagon) is NOT prescribed.
There is one Module for Application (Hexagon).
Examples of structuring inside Hexagon:
No packages inside the Hexagon (currently illustrated in BlueZone)
Packages inside the Hexagon (possible future for BlueZone):
Driver Ports (interfaces & their data)
Driven Ports (interfaces & their data)
Internals (implementation of driver ports)
Packages inside the Hexagon (Onion / Clean / DDD):
Application
Application Service (Use Case) Interfaces (aka Driver Ports)
Application Service (Use Case) Implementations
Domain
Domain Entities
Domain Services
Gateway Interfaces (aka Driven Ports)
Any other possibilities, because structure is not prescribed
Note: Usage of the word "packages" is for Java apps. In .NET, it's "namespaces".
Tests in Hexagonal Architecture
Each Driver Port has its own corresponding Test module. We may use a different test framework per Test module (e.g. TestNG, Cucumber). Test modules are illustrated in BlueZone which is theoretically most closely aligned with the Hexagonal Architecture diagram, however in practice, we’d typically have a Tests folder inside the source modules, rather than separate.
Furthermore, there are two approaches to coupling between Tests and the Application:
Tests targeting Driving Ports, including a special Driving Port which hides away the Driven Ports from the Test (in BlueZone: ForConfiguringApp port)
Tests targeting Driving Ports, but also dependent on Driven Ports, so that we can directly access the Test Doubles