How do
Domain-Driven Design
and
software architecture
play on the frontend?
Slide 2
Slide 2 text
@talyssonoc
Brazilian
codeminer42.com
Glad to be here
Talysson
Slide 3
Slide 3 text
What is the "domain"?
“The sphere of knowledge and activity around
which the application logic revolves”
Source:
Slide 4
Slide 4 text
What is Domain-Driven Design?
- DDD is a software design practice focused on the domain
- The domain is described through a model cultivated by the
developers in collaboration with the domain experts
- Model as in "model aircraft"
- DDD practitioners prefer to use architectures that are centered
on the domain
Slide 5
Slide 5 text
What is software architecture?
- It’s hard to define… but let’s give it a shot
- How the components of a system interact and have assigned
responsibilities prioritizing its success factors
- It is not file organization
- So, in a nutshell…
- The team high level understanding of how the system works
- Every system has an architecture, it’s better if it’s intentional
Slide 6
Slide 6 text
User interface
Application
(use cases)
Domain
(business logic)
Infrastructure
Layers of responsibility in an architecture
UI frameworks, styling,
I18n, formatters, …
"Make illegal states unrepresentable"
Source:
Entities, Value Objects,
Aggregates, Invariants and Repositories*
Slide 9
Slide 9 text
Example: Diary application
- The Diary is composed of entries
- An Entry (an aggregate) is composed of:
- ID: a number
- Title: longer than 5 characters
- Content: longer than 60 characters
- Date: current or in the past
Slide 10
Slide 10 text
How do we create a valid Entry without an ID?
Slide 11
Slide 11 text
Illegal state
Slide 12
Slide 12 text
"Make implicit concepts explicit"
How does DDD handle this?
Is it really an Entry?
Or is it… the intent to create/edit an Entry?
Make the intent explicit
Slide 13
Slide 13 text
No content
Slide 14
Slide 14 text
A new domain concept only for the frontend?!
The frontend is a Bounded Context itself
⚠ Domain logic on the frontend is a matter of UX
And it fits really well with…
Slide 15
Slide 15 text
* Repositories
Responsible for abstracting persistence
Their interface belongs to the domain!
“Provides technical capabilities that
support the higher layers”
Examples:
- interaction with APIs (REST, GraphQL, WebSockets)
- interaction with the browser (cookies, LocalStorage)
Slide 18
Slide 18 text
Not an API abstraction
Slide 19
Slide 19 text
Repository implementations
Respect the rules determined by the domain
Abstract technical details
Slide 20
Slide 20 text
Actual API abstraction
* Error handling omitted for brevity
What are use cases?
"[...] All the ways of using a system to achieve a
particular goal for a particular user"
Source:
Slide 23
Slide 23 text
What make use cases on the frontend different?
On backend applications, use cases
(aka interactors) are mostly transactional
On the frontend (and mobile, and desktop, …)
use cases are stateful
But transactional use cases are the exception
Slide 24
Slide 24 text
Example: “Create entry” use case
- User clicks the "New entry" button
- User edits the new entry data
- The title can be edited (state)
- The content can be edited (state)
- The date can be edited (state)
- User finishes it clicking the "Add" button
Slide 25
Slide 25 text
Mutability
No reactivity from changes
Slide 26
Slide 26 text
How to keep the application layer stateful,
reactive, and decoupled from the UI layer?
By extracting the state from the use case
Making the use case immutable
Slide 27
Slide 27 text
Injected state
management
Immutability
Isolated state initialisation
Slide 28
Slide 28 text
Plugging it in into the UI layer
(An example with React hooks)
Leave reactivity and state management to the UI layer to implement
Slide 29
Slide 29 text
User interface
Application
(use cases)
Domain
(business logic)
Infrastructure
What about global state management?
Slide 30
Slide 30 text
Global state management: the layer #5
User interface
Application
(use cases)
Domain
(business logic)
Infrastructure
State
management
and server cache
Provides data
Updates the state after application events
Slide 31
Slide 31 text
Updating global state after application events
State updates are triggered as consequences,
not being actively requested by the UI
Similar to backend event-driven architectures
Slide 32
Slide 32 text
User interface Application
Global
state
management
Requests data
and subscribe
to changes
Notify changes
Instruction
Event
Slide 33
Slide 33 text
No content
Slide 34
Slide 34 text
Toolkit
Slide 35
Slide 35 text
No content
Slide 36
Slide 36 text
Architecture layers of frontend applications
User interface
Application
(use cases)
Domain
(business logic)
Infrastructure
Provides data
State
management
and server cache
Updates the state after application events
Slide 37
Slide 37 text
Final considerations
- There is a lot "canonical" programming knowledge out there that
applies (or can be adapted) to the frontend, use it!
- DDD and layered architecture
- Dependency injection (aka DI)
- Service-oriented architecture
- CQRS and event sourcing
- Use architecture to isolate complexity
- Be patient, it'll pay off
Slide 38
Slide 38 text
Example - Diary application
github.com/talyssonoc/frontend-architecture-jsconf-chile-2023