Architecturally Expressive Package Structure

Learn what an architecturally expressive package structure looks like and how it can help you develop Clean Architecture.

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.