Explicit Architecture: DDD, Hexagonal, Onion, Clean, CQRS, How I Put It All Together

Download as pdf or txt
Download as pdf or txt
You are on page 1of 37

Explicit Architecture

DDD, Hexagonal, Onion, Clean, CQRS, …


How I put it all together
Me
Portuguese

Former high school teacher

Senior developer @ Werkspot

Wannabe Software Architect

Enjoys good food, good wine, coding,


snowboarding, traveling, laying on
the beach!

Loves Blackie!

2
What this talk is about

Ideas of people far smarter and experienced than me

My own mental map of how those ideas fit together

3
No silver bullets,

No holy grail,

No one boot fits all!

4
Software Architecture

▪ Driven by the requirements

▪ What is difficult to change later on in the project

▪ The broad strokes, the structure, the components, and


relations between components

▪ Standards for consistency of results and lightweight of


processes

5
Those who can not remember the past are
doomed to repeat it.

George Santayana
Popularized by Winston Churchill

6
Mainstream Paradigms, Styles & Patterns

Non-structured Programming Monolith

Structured Programming CORBA

Procedural & Functional Prog. Service Oriented Architecture

Object Oriented Programming Enterprise Service Bus

Design Patterns Microservices

Nanoservices (lambdas, serverless)

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

Classes, Abstracts, Interfaces / Files

Namespaces / Folders

12
1996/7 Software Development Principles
Among other principles:

SRP – The Single Responsibility Principle


A class should have only one reason to change
(A code unit should have only one single responsibility)

CCP – The Common Closure Principle


Classes that change together are packaged together

CRP – The Common Reuse Principle


Classes that are used together are packaged together

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

1st tier User Interface


Rich client

Infrastructure
Business Logic

2nd tier

Data

15
1990s/00s Layered Architecture - 3 tier / n tier

1st tier User Interface


Views rendered in a browser

Network, Framework, Logging


Infrastructure
Presentation
Views
2nd tier

Business Logic

3rd tier
Data
Database server

16
1992 Entity Boundary Interactor Architecture
How to connect the application to
delivery mechanisms and tools

The Entity objects hold the data used by the


system and all the behaviour naturally coupled
to this data.

The Interactor objects will hold behaviour not


naturally tied to any of the other types of
objects.

The Boundary objects model the interface


with the system.
By Ivar Jacobson
17
2003 Domain Driven Design
Generic Subdomain Context Map

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

Presentation / UI Infrastructure Layer


Layer

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

The most stable business


rules objects (entities and
their VOs, Enums, ...)

By Jeffrey Palermo
22
2011 Screaming Architecture
Program

Each domain concept becomes


Controllers
a 1st level of encapsulation
Helpers
Program
Models
HealthCare Accounting Inventory
Util (Component) (Component) (Component)

Views Use Cases Use Cases

Domain Domain Domain

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

workers Domain Layer


Entities, Collections, VOs,
...
Domain Services

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]

“[...] the code should reflect the architecture. In other words, if


I look at the code, I should be able to clearly identify each of
the components [...]”
Simon Brown [2]
[1] https://resources.sei.cmu.edu/asset_files/Presentation/2013_017_001_48651.pdf
[2] http://www.codingthearchitecture.com/2014/06/01/an_architecturally_evident_coding_style.html

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

Make the architecture explicit

Design must favor modularity and encapsulation

Build Monoliths, but plan Microservices

Enforce the architecture


36
References
▪ These slides:
https://www.slideshare.net/hgraca/explicit-architecture

▪ A code sample:
https://github.com/hgraca/explicit-architecture-php

▪ My Software Architecture blog posts with all references:


https://www.herbertograca.com/2017/07/03/the-software-architecture-chronicles

Thanks to
▪ Francesco Mastrogiacomo for helping me with some infographics

▪ Marijn Koesen, Alejandro Barba and Rodrigo Prestes for reviewing my talk

37

You might also like