Architecturally Expressive Package Structure
Learn what an architecturally expressive package structure looks like and how it can help you develop Clean Architecture.
We'll cover the following
Project structure
In a Hexagonal Architecture, we have entities, use cases, incoming and outgoing ports, and incoming and outgoing (or “driving” and “driven”) adapters as our main architectural elements. Let’s fit them into a package structure that expresses this architecture:
buckpal
└── account
├── adapter
| ├── in
| | └── web
| | └── AccountController
| ├── out
| | └── persistence
| | ├── AccountPersistenceAdapter
| | └── SpringDataAccountRepository
├── domain
| ├── Account
| └── Activity
└── application
├── service
| └── SendMoneyService
└── port
├── in
| └── SendMoneyUseCase
└── out
├── LoadAccountPort
└── UpdateAccountStatePort
Explanation
Each element of the architecture can directly be mapped to one of the packages. On the highest level, we again have a package named account
, indicating that this is the module implementing the use cases around an Account
.
On the next level, we have the domain
package containing our domain model. The application
package contains a service layer around this domain model. The SendMoneyService
implements the incoming port interface SendMoneyUseCase
and uses the outgoing port interfaces LoadAccountPort
and UpdateAccountStatePort
, which are implemented by the persistence adapter.
The adapter
package contains the incoming adapters that call the application layers’ incoming ports and the outgoing adapters that provide implementations for the application layers’ outgoing ports. In our case, we’re building a simple web application with the adapters web
and persistence
, each having its own sub-package.
Phew, that’s a lot of technical-sounding packages. Isn’t that confusing?
Get hands-on with 1400+ tech skills courses.