The Ultimate Guide to Choosing WordPress Pros and Cons
Hexagonal
1. Hexagonal Architecture: Why Architecture
Hexagonal architecture is a specific instance of an architecture
pattern. Why do we need one at all?
Make software easier to change
Make software easier to test
Make software easier to reason about
Make software easier to write with fewer bugs
Reduce the future cost of changing your mind later, about
nearly anything
Michael Nash Hexagonal Architecture
2. Hexagonal Architecture: Definition
What is Hexagonal Architecture?
An alternative to the “standard layered model”
Developed by Alistair Cockburn
Later called Ports and Adapters
Also called the Onion Architecture
Involves application of the Dependency Inversion Principle
Michael Nash Hexagonal Architecture
3. Hexagonal Architecture: Contrast
What is the Standard Layered Model?
UI
Application
Domain
Network and database
Hexagonal architecture rejects the notion that any of these layers
except the domain are different from one another. E.g. a user
sitting at a UI is not much different than a flat file full of test
cases, or a network and a database.
Michael Nash Hexagonal Architecture
6. Hexagonal Architecture: Value
Why Hexagonal Architecture?
What does this architecture buy us?
Symmetrical
Verifiable – you can tell when you’ve got it by inspection
Decouple core logic (the domain) from infrastructure
Always possible to test everything easily
Infrastructure changes are not relevant to the domain logic
Makes package and module structure consistent and easy to
navigate
Natural fit with DDD and EDA
Language and framework agnostic
Excellent fit with functional programming
Michael Nash Hexagonal Architecture
7. Hexagonal Architecture: Ports and Adapters
Infrastructure services can easily be replaced with others
Michael Nash Hexagonal Architecture
8. Dependency Inversion Principle
To apply Hexagonal architecture, we use the dependency inversion
principle
Specific top-level package structure
Careful management of imports and dependency management
Common classes depend on nothing (no IO, utilities only)
Domain classes depend only on common classes and each
other
Services classes depend on domain, adapt to infrastructure
Infrastructure classes depend on services and domain
Michael Nash Hexagonal Architecture
10. Dependency Inversion Principle: Common
The Common package contains only shared utility classes
No I/O!
String utilities
Date utilities
Random numbers
Data structures
NOT what we currently call “common”
Michael Nash Hexagonal Architecture
11. Dependency Inversion Principle: Domain
The Domain package contains only business domain classes and
functions
Depends ONLY on other domain classes and common classes
Can use abstractions like logging (traits only)
Contains domain logic – avoid anemic domain!
No I/O
Can contain DDD services for operations that span aggregates
No DTOs
No annotations
Use types, not primitives wherever possible
Michael Nash Hexagonal Architecture
12. Dependency Inversion Principle: Services
The Services package contains the service classes used by the ports
and adapters to interact with the domain
Depends ONLY on domain and common
Expose operations needed by the adapters
No I/O
Could contain Repositories
No event handlers (these are infrastructure)
No REST routing (again, infrastructure)
No DTOs
No annotations
Michael Nash Hexagonal Architecture
13. Dependency Inversion Principle: Infrastructure
The Infrastructure package contains the adapters that connect the
services and the domain to the outside world
Can depend on any other package as required
Contains sub-packages for specific adapters (e.g. http,
eventbus, mongo)
I/O goes here – all of it
Calls services and domain
REST routing goes here
Implementations of repositories go here
DTOs go here
Guice module, dependency injection goes here
Michael Nash Hexagonal Architecture
14. Hexagonal Architecture: Action Plan
How do we get there? What’s the plan?
Review Hierarchy (now), make sure we all understand the
desired outcome
In other modules, create top-level packages domain, common,
services and infrastructure
Refactor into proper package structure, decoupling as required
Decouple from deprecated common modules
Refactor spray-service-common and submodules into re-usable
infrastructure modules
Use Crucible to review and discuss refactors
Specific stories to refactor each module
Decouple EventBus from our domain (make domain-agnostic)
Adopt single-source tree view to facilitate refactorings
Michael Nash Hexagonal Architecture
15. Hexagonal Architecture: Single Sourcetree View
A single bounded context should be visible as a single logical
source tree
No more p2build plugin
Refactoring greatly simplified
No more versions of common
Executable artifacts become a deploy-time question: can
change as needed
Acheivable “virtually” right away with git sub-modules
(ListingDistributionContext)
Adding new Event types (for example) becomes trivial
One git repo (logically, if not physically at first)
Decouple EventBus from our domain (make domain-agnostic)
Integration tests become trivial (no need to launch multiple
jars)
Michael Nash Hexagonal Architecture
16. Hexagonal Architecture: Conclusion
We want the benefits of hexagonal architecture, hence the
refactors
Questions?
Michael Nash Hexagonal Architecture