Explicit Architecture: DDD, Hexagonal, Onion, Clean, CQRS, How I Put It All Together
Explicit Architecture: DDD, Hexagonal, Onion, Clean, CQRS, How I Put It All Together
Explicit Architecture: DDD, Hexagonal, Onion, Clean, CQRS, How I Put It All Together
Loves Blackie!
2
What this talk is about
3
No silver bullets,
No holy grail,
4
Software Architecture
5
Those who can not remember the past are
doomed to repeat it.
George Santayana
Popularized by Winston Churchill
6
Mainstream Paradigms, Styles & Patterns
7
Software development evolution
Modularity
(Low Coupling)
Encapsulation
(High Cohesion)
8
Monolith m es
dn ga
t h o p l ace
n d me e a nin v ious de
sa m b
Clas n’t conve
y No o put co
do to
≠
en cy le
e n d st ab
Dep ess Unte
m
No clear and enforced design rules
9
Big Ball Of Mud
10
Granularity levels
11
Granularity levels
Libraries
Plain code
Methods
Namespaces / Folders
12
1996/7 Software Development Principles
Among other principles:
By Robert C. Martin
13
1960s/70s Layered Architecture - 1 tier
Dumb Client
Infrastructure
User Interface
1 tier Business Logic
Data
14
1980s/90s Layered Architecture - 2 tier
Infrastructure
Business Logic
2nd tier
Data
15
1990s/00s Layered Architecture - 3 tier / n tier
Business Logic
3rd tier
Data
Database server
16
1992 Entity Boundary Interactor Architecture
How to connect the application to
delivery mechanisms and tools
CRM
Categories Domain
Ubiquitous
Expert
language
Interaction
Core Domain Event Storming?
Products
Shared
Kernel Orders
r on
La rupti
or
ye
ti C
An
Shipping
Locations Legacy
or external
Subsystem
Support Subdomain
By Eric Evans
18
2003 Domain Driven Design
Generic Subdomain Context Map
OrderCreated Flow direction
Event
DN
CRM Command
CreateComplaintCase Query
...
UP Up Stream
DN Down Stream
Categories Domain
Ubiquitous
Expert
language
Interaction
Core Domain Event Storming?
Products
AddProduct UP
EditProduct
DeleteProduct
Shared
Kernel Orders
r on
...
La rupti
UP
or
ye
ti C
An
DN
DN
Shipping
CreateShipment
UP
UP
Locations Legacy
getLocationDetails
or external
Subsystem
Support Subdomain
By Eric Evans
19
2005 Ports & Adapters
How to connect the application to
delivery mechanisms and tools
Primary / Driver Secondary / Driven
Adapters Adapters
By Alistair Cockburn
20
2005 Ports & Adapters rudimentar example
Primary / Driver Adapter Secondary / Driven Adapter
class LoginController final class PhoneNumberValidator
{ implements PhoneNumberValidatorInterface
{
/…
/…
public function __construct(
AuthenticationServiceInterface $authenticationService public function __construct(PhoneNbrUtil $phoneNumberUtil)
) { {
$this->authenticationService = $authenticationService; $this->phoneNumberUtil = $phoneNumberUtil;
} }
/… /…
public function login(ServerRequestInterface $request): void public function isValid(string $number): void
{ {
/… if (!$this->phoneNumberUtil->isValidNumber($number)) {
$this->authenticationService->login( throw new PhoneNumberInvalidException($number);
$request->getArgument('username'), }
$request->getArgument(password) }
); }
/…
}
}
By Alistair Cockburn
21
2008 Onion Architecture
Domain Services
Application Services
Domain logic involving
several entities Entry and exit points of the
application (use cases)
Domain Model
By Jeffrey Palermo
22
2011 Screaming Architecture
Program
Data Data
By Robert C. Martin
23
2012 Clean Architecture
By Robert C. Martin
24
2006 Command Query Responsibility Segr.
Presentation
Views, Input Controllers
View
Command Query
Model
Command BUS Query BUS
validate open handle close
transaction OR transaction
enqueue
Application
Query Handler
Application Layer
async Command Handler
queue App. Services, Event
Listeners
Persistence
Repositories, Query Objects, ORM By Greg Young
25
26
More than concentric layers
27
Architecturally evident coding style
“[...] an architecturally evident coding style that lets you drop
hints to code readers so that they can correctly infer the
design.”
George Fairbanks [1]
28
Reflect the architecture in code
src/
29
UserInterface
API
GraphQl
<component A>
<component B>
...
Rest
<component A>
<component B>
...
Console
<component A>
<component B>
…
Website
Admin
<component A>
...
Consumer
<component A>
...
30
Infrastructure Implementation of the adapters
CommandBus that adapt a 3rd party tool to a
core port.
<vendor-adapter>
…
EventBus
<vendor-adapter>
…
Notifications
<vendor-adapter>
…
Search
<vendor-adapter>
…
Persistence
<vendor-adapter>
…
31
Core
Component Bounded contexts
Blog
Application Use cases and
supporting code
Listener
Notification
Query
Repository
Service
Domain Invariants: Entities,
and their Enums,
Post ValObjs, ...
Comment
Tag
Port Abstractions shared by the
bounded contexts, which are a
Auth connection to a 3rd party tool.
EventDispatcher
...
SharedKernel
Code shared by the bounded contexts
so they can communicate: IDs, Events,
Component …
This can eventually be extracted to a
... repository and shared among projects.
Port In a polyglot system it must be
... descriptive.
32
Reflect the architecture in code
src/
User Interface
Core
Component
<ComponentA>
Application
Domain
Port
SharedKernel
Infrastructure
lib/
lang-extension/
src/
tests/
33
Enforcing the Architecture
paths:
-
./lib/php-extension/src
- ./src
layers:
- name: Controller
collectors:
- type: className
regex:
.*Controller$
# …
ruleset:
Controller:
- Service
- Query
- Repository Start to create an AstMap for35 Files.
...................................
AstMap created.
Service: start emitting dependencies"InheritanceDependencyEmitter"
- Query start emitting dependencies"BasicDependencyEmitter"
- Repository end emitting dependencies
start flatten dependencies
end flatten dependencies
Query: ~
collecting violations.
formatting dependencies.
Repository: ~
Found 0 Violations
https://github.com/sensiolabs-de/deptrac https://github.com/hgraca/explicit-architecture-php/tree/dev
34
Takeaways ...
A code unit must have only one logic place to live
▪ A code sample:
https://github.com/hgraca/explicit-architecture-php
Thanks to
▪ Francesco Mastrogiacomo for helping me with some infographics
▪ Marijn Koesen, Alejandro Barba and Rodrigo Prestes for reviewing my talk
37