SlideShare a Scribd company logo
1 of 229
The aggregate is dead!
Long live the aggregate!
@_sara_p_
Sara Pellegrini
@MilanSavic14
Milan Savic
The aggregate
The aggregate
The aggregate
An aggregate is a cluster of associated objects
that we treat as a unit for the purpose of data changes.
From blue book - Domain-Driven Design: Tackling Complexity in the Heart of Software - Eric Evans
The aggregate is ... confusing
From theory to practice
From theory to practice
Cluster the ENTITIES and VALUE OBJECTS into AGGREGATES and define
boundaries around each.
From blue book - Domain-Driven Design: Tackling Complexity in the Heart of Software - Eric Evans
From theory to practice
Cluster the ENTITIES and VALUE OBJECTS into AGGREGATES and define
boundaries around each.
Choose one ENTITY to be the root of each AGGREGATE, and control all access to
the objects inside the boundary through the root.
From blue book - Domain-Driven Design: Tackling Complexity in the Heart of Software - Eric Evans
From theory to practice
Cluster the ENTITIES and VALUE OBJECTS into AGGREGATES and define
boundaries around each.
Choose one ENTITY to be the root of each AGGREGATE, and control all access to
the objects inside the boundary through the root. Allow external objects to hold
reference to the root only.
From blue book - Domain-Driven Design: Tackling Complexity in the Heart of Software - Eric Evans
Event Storming
Education domain
Event Storming
Education domain
1) A course cannot accept more than N students
Event Storming
Education domain
1) A course cannot accept more than N students
2) N, the Course Capacity, can change any time
to any positive integer different from the current one
Event Storming
Education domain
1) A course cannot accept more than N students
2) N, the Course Capacity, can change any time
to any positive integer different from the current one
(even if the number of currently subscribed students is larger than the new value)
time
Course
Created
Event
time
Course
Created
Event
Student
Subscribed
to Course
Event
time
Course
Created
Event
Student
Subscribed
to Course
Event
Student
Unsubscribed
from Course
Event
time
Course
Created
Event
Student
Subscribed
to Course
Event
Student
Unsubscribed
from Course
Event
Course
Capacity
Changed
Event
time
Course
Created
Event
Student
Subscribed
to Course
Event
Student
Unsubscribed
from Course
Event
Course
Capacity
Changed
Event
Create
Course
Command
Subscribe
Student to
Course
Command
Unsubscribe
Student to
Course
Command
Update
Course
Capacity
Command
time
Story Telling
Story Telling
Storytelling is at the heart of human communication.
Story Telling
Storytelling is at the heart of human communication.
Storytelling does not require any special competence/skill.
Story Telling
Storytelling is at the heart of human communication.
Storytelling does not require any special competence/skill.
It helps break down the barriers between technicians and business experts.
The aggregate is the boundary of consistency
The aggregate is the boundary of consistency
When a change to any object with the aggregate boundary is committed, all
invariants of the whole aggregate must be satisfied.
From blue book - Domain-Driven Design: Tackling Complexity in the Heart of Software - Eric Evans
Course
Created
Event
Student
Subscribed
to Course
Event
Student
Unsubscribed
from Course
Event
Course
Capacity
Changed
Event
Create
Course
Command
Subscribe
Student to
Course
Command
Unsubscribe
Student to
Course
Command
Update
Course
Capacity
Command
Course
Created
Event
Student
Subscribed
to Course
Event
Student
Unsubscribed
from Course
Event
Course
Capacity
Changed
Event
Create
Course
Command
Subscribe
Student to
Course
Command
Unsubscribe
Student to
Course
Command
Update
Course
Capacity
Command
1) A course cannot accept more than N students
2) N, the Course Capacity, can change any time to any
positive integer different from the current one
Course
Created
Event
Student
Subscribed
to Course
Event
Student
Unsubscribed
from Course
Event
Course
Capacity
Changed
Event
Create
Course
Command
Subscribe
Student to
Course
Command
Unsubscribe
Student to
Course
Command
Update
Course
Capacity
Command
Course
Course
Course Course
1) A course cannot accept more than N student
2) N, the Course Capacity, can change any time to any
positive integer different from the current one
Aggregate does not fit
Story Telling
Aggregate does not fit with Story Telling
Aggregate does not fit with Story Telling
It is not naturally part of the story: the story teller is forced to add this element
Aggregate does not fit with Story Telling
It is not naturally part of the story: the story teller is forced to add this element
Should business experts understand what a consistency boundary is?
Aggregate does not fit with Story Telling
It is not naturally part of the story: the story teller is forced to add this element
Should business experts understand what a consistency boundary is?
Leads back to the old modelling-first/data centric approach.
Moves the focus from the behavior to the model.
Aggregate Mixes technical and
business aspects
The nouns become our aggregates
Course
Created
Event
Student
Subscribed
to Course
Event
Student
Unsubscribed
from Course
Event
Course
Capacity
Changed
Event
Create
Course
Command
Subscribe
Student to
Course
Command
Unsubscribe
Student to
Course
Command
Update
Course
Capacity
Command
Course
Course
Course Course
The nouns become our aggregates
Course
Created
Event
Student
Subscribed
to Course
Event
Student
Unsubscribed
from Course
Event
Course
Capacity
Changed
Event
Create
Course
Command
Subscribe
Student to
Course
Command
Unsubscribe
Student to
Course
Command
Update
Course
Capacity
Command
Course
Course
Course Course
The course
Course
Create Course Command
Subscribe Student to Course
Command
Unsubscribe Student to Course
Command
Update Course Capacity
Command
Course Created
Event
Student Subscribed to Course
Event
Student Unsubscribed from
Course Event
Course Capacity Changed
Event
The COURSE
aggregate
<<Aggregate Root>>
Course Subscription
*
The COURSE
aggregate
<<Aggregate Root>>
Course Subscription
*
Subscribe Student to Course
Command
Unsubscribe Student to Course
Command
The COURSE
aggregate
<<Aggregate Root>>
Course Subscription
*
Subscribe Student to Course
Command
Unsubscribe Student to Course
Command
The COURSE
aggregate
<<Aggregate Root>>
Course Subscription
*
Subscribe Student to Course
Command
Unsubscribe Student to Course
Command
Update Course Capacity
Command
The COURSE
aggregate
<<Aggregate Root>>
Course Subscription
*
Subscribe Student to Course
Command
Unsubscribe Student to Course
Command
Update Course Capacity
Command
Event sourced COURSE aggregate
Course Created Event
Student Subscribed to Course
Event
Student Unsubscribed from
Course Event
Course Capacity Changed
Event
Event sourced COURSE aggregate
Course Created Event
Student Subscribed to Course
Event
Student Unsubscribed from
Course Event
Course Capacity Changed
Event
Subscribe Student to Course
Command
Unsubscribe Student to Course
Command
Event sourced COURSE aggregate
Course Created Event
Student Subscribed to Course
Event
Student Unsubscribed from
Course Event
Course Capacity Changed
Event
Subscribe Student to Course
Command
Unsubscribe Student to Course
Command
Update Course
Capacity Command
Event Storming of this problem:
Education domain
1) A course cannot accept more than N students
2) N, the Course Capacity, can change any time
to any positive integer different from the current one
(even if the number of currently subscribed students is larger than the new value)
3) The course title can change any time
to any title different from the current one
Event Storming of this problem:
Education domain
1) A course cannot accept more than N students
2) N, the Course Capacity, can change any time
to any positive integer different from the current one
(even if the number of currently subscribed students is larger than the new value)
3) The course title can change any time
to any title different from the current one
Course
Renamed
Event
Course
Renamed
Event
Rename
Course
Command
Course
Renamed
Event
Rename
Course
Command
Course
The larger the Aggregate
the greater the contention
The boundary of consistency
is also the boundary of concurrency
Concurrent command execution
Concurrent command execution
Update Course
Capacity Command
Rename Course
Command
Concurrent command execution
Update Course
Capacity Command
Rename Course
Command
<<Aggregate Root>>
Course Subscription
*
<<Aggregate Root>>
Course Subscription
*
Concurrent command execution
Update Course
Capacity Command
Rename Course
Command
<<Aggregate Root>>
Course Subscription
*
<<Aggregate Root>>
Course Subscription
*
Concurrent command execution
Update Course
Capacity Command
Rename Course
Command
<<Aggregate Root>>
Course Subscription
*
<<Aggregate Root>>
Course Subscription
*
Concurrent command execution
Update Course
Capacity Command
Rename Course
Command
<<Aggregate Root>>
Course Subscription
*
<<Aggregate Root>>
Course Subscription
*
Alternative solution
Alternative solution
<<Aggregate Root>>
Course Subscription
*
<<Aggregate Root>>
Course
Subscriptions
Subscription
*
Alternative solution: CourseInfo & CourseSubscription
<<Aggregate Root>>
Course
Info
Course CourseInfo & CourseSubscriptions
Course
More contention
Simpler
CourseInfo & CourseSubscriptions
Course
More contention
Simpler
CourseInfo & CourseSubscriptions
Less contention
Course
More contention
Simpler
CourseInfo & CourseSubscriptions
Less contention
Additional complexity
➔ Management of multiple aggregates
What if model changes…
What if model changes…
Now what???
What if model changes…
Now what???
State Persisted Aggregates
- Script
Event Sourced Aggregates
- ???
What if model changes…
Now what???
State Persisted Aggregates
- Script
Event Sourced Aggregates
- ???
What if model changes…
Now what???
State Persisted Aggregates
- Script
Event Sourced Aggregates
- ???
What if model changes…
Now what???
State Persisted Aggregates
- Script
Event Sourced Aggregates
- ???
Refactoring with Event Sourcing
Course
Created
….
Course
Renamed
Course
Capacity
Changed
….
Course
Capacity
Changed
…. ….
Refactoring with Event Sourcing
Course
Created
….
Course
Renamed
Course
Capacity
Changed
….
Course
Capacity
Changed
…. ….
….
Refactoring with Event Sourcing
Course
Created
….
Course
Renamed
Course
Capacity
Changed
….
Course
Capacity
Changed
…. ….
Course
Subscriptions
Created
….
Course
Info
Created
Refactoring with Event Sourcing
Course
Created
….
Course
Renamed
Course
Capacity
Changed
….
Course
Capacity
Changed
…. ….
Course
Subscriptions
Created
….
…. ….
Course
Info
Created
Refactoring with Event Sourcing
Course
Created
….
Course
Renamed
Course
Capacity
Changed
….
Course
Capacity
Changed
…. ….
Course
Subscriptions
Created
….
Course
Renamed
…. ….
Course
Info
Created
Refactoring with Event Sourcing
Course
Created
….
Course
Renamed
Course
Capacity
Changed
….
Course
Capacity
Changed
…. ….
Course
Subscriptions
Created
….
Course
Renamed
Course
Capacity
Changed
….
Course
Capacity
Changed
…. ….
Course
Info
Created
Refactoring with Event Sourcing
Course
Created
….
Course
Renamed
Course
Capacity
Changed
….
Course
Capacity
Changed
…. ….
Course
Subscriptions
Created
….
Course
Renamed
Course
Capacity
Changed
….
Course
Capacity
Changed
…. ….
Course
Info
Created
Aggregates
Are Hard to Refactor
Event Storming of this problem:
Education domain
1) A course cannot accept more than N students
2) N, the Course Capacity, can change any time
to any positive integer different from the current one
(even if the number of currently subscribed students is larger than the new value)
3) The course title can change any time
to any title different from the current one
4) The student cannot join more than 10 courses
Event Storming of this problem:
Education domain
1) A course cannot accept more than N students
2) N, the Course Capacity, can change any time
to any positive integer different from the current one
(even if the number of currently subscribed students is larger than the new value)
3) The course title can change any time
to any title different from the current one
4) The student cannot join more than 10 courses
Student
Created
Event
time
Student
Created
Event
time
Create
Student
Command
Student
Created
Event
Student
Subscribed
to Course
Event
time
Create
Student
Command
Student
Created
Event
Student
Subscribed
to Course
Event
Student
Unsubscribed
from Course
Event
time
Create
Student
Command
Create
Student
Command
Subscribe
Student to
Course
Command
Student
Created
Event
Student
Subscribed
to Course
Event
Unsubscribe
Student from
Course
Command
Student
Unsubscribed
from Course
Event
time
Course
Created
Event
Student
Subscribed
to Course
Event
Student
Unsubscribed
from Course
Event
Course
Capacity
Changed
Event
Create
Course
Command
Subscribe
Student to
Course
Command
Unsubscribe
Student to
Course
Command
Update
Course
Capacity
Command
Course
Course
Course Course
Create
Student
Command
Subscribe
Student to
Course
Command
Student
Created
Event
Student
Subscribed
to Course
Event
Unsubscribe
Student from
Course
Command
Student
Unsubscribed
from Course
Event
4) The student cannot join more than 10 courses
Create
Student
Command
Subscribe
Student to
Course
Command
Student
Created
Event
Student
Subscribed
to Course
Event
Unsubscribe
Student from
Course
Command
Student
Unsubscribed
from Course
Event
Student Student Student
4) The student cannot join more than 10 courses
Create Student
Command
Subscribe Student to
Course Command
Student Created
Event
Student Subscribed
Course Event
Student
Unsubscribe Student from
Course Command
Student Unsubscribed from
Course Event
The STUDENT aggregate
<<Aggregate Root>>
Student Subscription
*
We need some form of synchronization...
We need some form of synchronization...
Subscribe Student to
Course Command
Saga
We need some form of synchronization...
Subscribe Student to
Course Command
Saga
We need some form of synchronization...
Subscribe Student to
Course Command
Subscribe Student to
Course Command
Subscribe Student to
Course Command
Student
Course
1
1
Saga
We need some form of synchronization...
Subscribe Student to
Course Command
Subscribe Student to
Course Command
Subscribe Student to
Course Command
Student Subscribed
Course Event
Student Subscribed
Course Event
Student
Course
1
1
Saga
We need some form of synchronization...
Subscribe Student to
Course Command
Subscribe Student to
Course Command
Subscribe Student to
Course Command
Student Subscribed
Course Event
Student
Course
1
1
Saga
We need some form of synchronization...
Subscribe Student to
Course Command
Subscribe Student to
Course Command
Subscribe Student to
Course Command
Student Subscribed
Course Event
Student
Course
revert
1
1
2
Saga
We need some form of synchronization...
Subscribe Student to
Course Command
Subscribe Student to
Course Command
Subscribe Student to
Course Command
Student Subscribed
Course Event
Student
Course
revert
Unsubscribe Student
to Course Command
Student Unsubscribed
Course Event
Student
1
1
2
3
Transactions that span
Multiple Aggregates
Could Cause
Unnecessary Complexity
It's just a long transaction...
It's just a long transaction...
Long transaction are very common when the business rule spans bounded contexts.
It's just a long transaction...
Long transaction are very common when the business rule spans bounded contexts.
But when the rule spans multiple aggregates in the same bounded context?
It's just a long transaction...
Long transaction are very common when the business rule spans bounded contexts.
But when the rule spans multiple aggregates in the same bounded context?
Is this a necessary complexity or it can be avoided?
● Does not fit the story telling
● Does not fit the story telling
● Puts focus on model instead of behaviour
● Does not fit the story telling
● Puts focus on model instead of behaviour
● Mixes technical and business aspects
● Does not fit the story telling
● Puts focus on model instead of behaviour
● Mixes technical and business aspects
● Can cause unnecessary contention
● Does not fit the story telling
● Puts focus on model instead of behaviour
● Mixes technical and business aspects
● Can cause unnecessary contention
● Can cause unnecessary complexity
● Does not fit the story telling
● Puts focus on model instead of behaviour
● Mixes technical and business aspects
● Can cause unnecessary contention
● Can cause unnecessary complexity
● Hard to refactor
Is there a better way to implement the command model?
Is there a better way to implement the command model?
-
F
o
c
u
s
o
n
B
e
h
a
v
i
o
r
-
Lets restart from… story telling
Lets restart from… story telling
Lets restart from… story telling
Decision Decision Decision
Decision Decision
Lets restart from… story telling
Decision Decision Decision
Decision Decision
Lets restart from… story telling
Decision Decision Decision
Decision Decision
Lets restart from… story telling
Decision Decision Decision
Decision Decision
Lets restart from… story telling
Decision Decision Decision
Decision Decision
Lets restart from… story telling
Decision Decision Decision
Decision Decision
Focus on the decision
Focus on the decision
Decision block = Message handler
The message handler knows what it needs to make a decision
Focus on the decision
Decision block = Message handler
The message handler knows what it needs to make a decision
Event sourcing
Event sourcing
Event sourcing provides a huge advantage because it decouples
the persistence from the model needed for taking the decision
The message handler can build on the fly any model needed for
taking the decision starting from the correct event stream
Event sourcing
Event sourcing provides a huge advantage because it decouples
the persistence from the model needed for taking the decision
The message handler can build on the fly any model needed for
making the decision starting from the correct event stream
Event sourcing
Course
Created
Student
Created
….
Course
Renamed
….
Course
Capacity
Changed
….
Event store
Event sourcing
Course
Created
Student
Created
….
Course
Renamed
….
Course
Capacity
Changed
….
Update
Course
Capacity
Command
Event store
Event sourcing
Course
Created
Student
Created
….
Course
Renamed
….
Course
Capacity
Changed
….
Update
Course
Capacity
Command
Event store
Event sourcing
Course
Created
Student
Created
….
Course
Renamed
….
Course
Capacity
Changed
….
Update
Course
Capacity
Command
Decision based on the following
business rules:
● The course exists
● The new capacity is different from prev
Command Handler
Event store
Event sourcing
Course
Created
Student
Created
….
Course
Renamed
….
Course
Capacity
Changed
….
Update
Course
Capacity
Command
Decision based on the following
business rules:
● The course exists
● The new capacity is different from prev
Command Handler
Event store
Event sourcing
Course
Created
Student
Created
….
Course
Renamed
….
Course
Capacity
Changed
….
Update
Course
Capacity
Command
Decision based on the following
business rules:
● The course exists
● The new capacity is different from prev
Command Handler
Event store
Course
Capacity
Changed
Event Store
events = stream(AggregateIdentifier id)
events = stream(StreamQuery query)
Event Store
events = stream(AggregateIdentifier id)
events = stream(StreamQuery query)
Event Store
events = stream(AggregateIdentifier id)
events = stream(StreamQuery query)
Stream Query
Stream Query
{"StreamQuery": {
"DomainIdentifiers": [
{ "course": "7d9b35b6-b46a-43bf-8e4c-eb7e6c3a487d" }
], "Types": [
"CourseCreated",
"CourseCapacityChanged"]
}
}
Stream Query
{"StreamQuery": {
"DomainIdentifiers": [
{ "course": "7d9b35b6-b46a-43bf-8e4c-eb7e6c3a487d" }
], "Types": [
"CourseCreated",
"CourseCapacityChanged"]
}
}
Stream Query
{"StreamQuery": {
"DomainIdentifiers": [
{ "course": "7d9b35b6-b46a-43bf-8e4c-eb7e6c3a487d" }
], "Types": [
"CourseCreated",
"CourseCapacityChanged"]
}
}
Stream Query
{"StreamQuery": {
"DomainIdentifiers": [
{ "course": "7d9b35b6-b46a-43bf-8e4c-eb7e6c3a487d" }
], "Types": [
"CourseCreated",
"CourseCapacityChanged"]
}
}
The focus is on the Message Handler
The focus is on the Message Handler
Less waste of resources
No modelling phase
More flexibility
The focus is on the Message Handler
Less waste of resources
No upfront modelling required
The focus is on the Message Handler
Less waste of resources
No upfront modelling required
More flexibility
Concurrency
Course
Created
Student
Created
….
Course
Renamed
….
Course
Capacity
Changed
….
Concurrency
Update
Course
Capacity
Command
Rename
Course
Command
Course
Created
Student
Created
….
Course
Renamed
….
Course
Capacity
Changed
….
Concurrency
Update
Course
Capacity
Command
Rename
Course
Command
Course
Created
Student
Created
….
Course
Renamed
….
Course
Capacity
Changed
….
Decision based on the following
business rules:
● The course exists
● The new capacity is different from prev
Decision based on the following
business rules:
● The course exists
● The new name is different from prev one
Concurrency
Update
Course
Capacity
Command
Rename
Course
Command
Course
Created
Student
Created
….
Course
Renamed
….
Course
Capacity
Changed
….
Decision based on the following
business rules:
● The course exists
● The new capacity is different from prev
Decision based on the following
business rules:
● The course exists
● The new name is different from prev one
Concurrency
Update
Course
Capacity
Command
Rename
Course
Command
Course
Created
Student
Created
….
Course
Renamed
….
Course
Capacity
Changed
….
Course
Capacity
Changed
Course
Renamed
Decision based on the following
business rules:
● The course exists
● The new capacity is different from prev
Decision based on the following
business rules:
● The course exists
● The new name is different from prev one
Concurrency
Update
Course
Capacity
Command
Subscribe
Student to
Course
Command
Course
Created
Student
Created
….
Course
Renamed
….
Course
Capacity
Changed
….
Concurrency
Update
Course
Capacity
Command
Subscribe
Student to
Course
Command
Course
Created
Student
Created
….
Course
Renamed
….
Course
Capacity
Changed
….
Decision based on the following
business rules:
● The course exists
● The new capacity is different from prev
Decision based on the following
business rules:
● The course exists
● The number of current subscription is
LOWER than the capacity (N)
Concurrency
Update
Course
Capacity
Command
Subscribe
Student to
Course
Command
Course
Created
Student
Created
….
Course
Renamed
….
Course
Capacity
Changed
….
Decision based on the following
business rules:
● The course exists
● The new capacity is different from prev
Decision based on the following
business rules:
● The course exists
● The number of current subscription is
LOWER than the capacity (N)
Concurrency
Update
Course
Capacity
Command
Subscribe
Student to
Course
Command
Course
Created
Student
Created
….
Course
Renamed
….
Course
Capacity
Changed
….
Course
Capacity
Changed
Decision based on the following
business rules:
● The course exists
● The new capacity is different from prev
Decision based on the following
business rules:
● The course exists
● The number of current subscription is
LOWER than the capacity (N)
Concurrency
Update
Course
Capacity
Command
Subscribe
Student to
Course
Command
Course
Created
Student
Created
….
Course
Renamed
….
Course
Capacity
Changed
….
Course
Capacity
Changed
Student
Subscribed
to Course
Decision based on the following
business rules:
● The course exists
● The new capacity is different from prev
Decision based on the following
business rules:
● The course exists
● The number of current subscription is
LOWER than the capacity (N)
Concurrency
Update
Course
Capacity
Command
Subscribe
Student to
Course
Command
Course
Created
Student
Created
….
Course
Renamed
….
Course
Capacity
Changed
….
Course
Capacity
Changed
Student
Subscribed
to Course
Decision based on the following
business rules:
● The course exists
● The new capacity is different from prev
Decision based on the following
business rules:
● The course exists
● The number of current subscription is
LOWER than the capacity (N)
Event Store
append(Event[] events)
append(Event[] events, StreamQuery query, EventIdentifier lastEvent)
Event Store
append(Event[] events)
append(Event[] events, StreamQuery query, EventIdentifier lastEvent)
Event Store
append(Event[] events)
append(Event[] events, StreamQuery query, EventIdentifier lastEvent)
Conditional append
if (lastEventIdentifier(query) != lastEvent) {
rejectAppend();
}
Conditional append
if (lastEventIdentifier(query) != lastEvent) {
rejectAppend();
}
Warranty of consistency
The event(s) are appended only if the there is no other event matching the query
that has appended after the lastEvent
Concurrency
Update
Course
Capacity
Command
Subscribe
Student to
Course
Command
Course
Created
Student
Created
….
Course
Renamed
….
Course
Capacity
Changed
….
Decision based on the following
business rules:
● The course exists
● The new capacity is different from prev
Decision based on the following
business rules:
● The course exists
● The number of current subscription is
LOWER than the capacity (N)
...592
Concurrency
Update
Course
Capacity
Command
Subscribe
Student to
Course
Command
Course
Created
Student
Created
….
Course
Renamed
….
Course
Capacity
Changed
….
Course
Capacity
Changed
Decision based on the following
business rules:
● The course exists
● The new capacity is different from prev
Decision based on the following
business rules:
● The course exists
● The number of current subscription is
LOWER than the capacity (N)
...592 ...593
append(event, query, ...592)
Concurrency
Update
Course
Capacity
Command
Subscribe
Student to
Course
Command
Course
Created
Student
Created
….
Course
Renamed
….
Course
Capacity
Changed
….
Course
Capacity
Changed
Student
Subscribed
to Course
Decision based on the following
business rules:
● The course exists
● The new capacity is different from prev
Decision based on the following
business rules:
● The course exists
● The number of current subscription is
LOWER than the capacity (N)
...592 ...593
append(event, query, ...592)
Concurrency
Update
Course
Capacity
Command
Subscribe
Student to
Course
Command
Course
Created
Student
Created
….
Course
Renamed
….
Course
Capacity
Changed
….
Course
Capacity
Changed
Student
Subscribed
to Course
Decision based on the following
business rules:
● The course exists
● The new capacity is different from prev
Decision based on the following
business rules:
● The course exists
● The number of current subscription is
LOWER than the capacity (N)
...592 ...593
append(event, query, ...592)
...593 != ...592
Concurrency
Update
Course
Capacity
Command
Subscribe
Student to
Course
Command
Course
Created
Student
Created
….
Course
Renamed
….
Course
Capacity
Changed
….
Course
Capacity
Changed
Student
Subscribed
to Course
Decision based on the following
business rules:
● The course exists
● The new capacity is different from prev
Decision based on the following
business rules:
● The course exists
● The number of current subscription is
LOWER than the capacity (N)
...592 ...593
append(event, query, ...592)
...593 != ...592
Limited contention
Limited contention
Before the contention boundaries were those of the aggregate...
Now, the contention boundaries are those of the stream query
Limited contention
Before the contention boundaries were those of the aggregate...
Now, the contention boundaries are those of the stream query
Does not seem very artificial?
Student
Subscribed
to Course
Event
Student
Unsubscribed
from Course
Event
Subscribe
Student to
Course
Command
Unsubscribe
Student to
Course
Command
Course Course
Student
Subscribed
to Course
Event
Student
Unsubscribed
from Course
Event
Subscribe
Student to
Course
Command
Unsubscribe
Student to
Course
Command
Student Student
Course
Created
Student
Created
….
Course
Renamed
Course
Capacity
Changed
….
Student
Subscribed
to Course
Student
Subscribed
to Course
Course
Created
Student
Created
….
Course
Renamed
Course
Capacity
Changed
….
Student
Subscribed
to Course
Student
Subscribed
to Course
From the story-telling perspective
Student
Subscribed
to Course
Event
Student
Unsubscribed
from Course
Event
Subscribe
Student to
Course
Command
Unsubscribe
Student to
Course
Command
From the story-telling perspective
Student
Subscribed
to Course
Event
Student
Unsubscribed
from Course
Event
Subscribe
Student to
Course
Command
Unsubscribe
Student to
Course
Command
Decision Decision
Course
Created
Student
Created
….
Course
Renamed
Course
Capacity
Changed
….
Student
Subscribed
to Course
Student
Subscribed
to Course
Course
Created
Student
Created
….
Course
Renamed
Course
Capacity
Changed
….
Student
Subscribed
to Course
Student
Subscribed
to Course
Course
Created
Student
Created
….
Course
Renamed
Course
Capacity
Changed
….
Student
Subscribed
to Course
Student
Subscribed
to Course
Pure Events
Course
Created
Student
Created
….
Course
Renamed
Course
Capacity
Changed
….
Student
Subscribed
to Course
Student
Subscribed
to Course
Course
Created
Student
Created
….
Course
Renamed
Course
Capacity
Changed
….
Student
Subscribed
to Course
Student
Subscribed
to Course
Pure Events
Course: jdsj4 Student:gfh3j ---
Course: jdsj4 Course: jdsj4
--- Course: jdsj4 Student: gfh3j
Tags (Domain Identifiers)
Course
Created
Student
Created
….
Course
Renamed
Course
Capacity
Changed
….
Student
Subscribed
to Course
Student
Subscribed
to Course
Pure Events
Course: jdsj4 Student:gfh3j ---
Course: jdsj4 Course: jdsj4
--- Course: jdsj4 Student: gfh3j
Tags (Domain Identifiers)
Course
Created
Student
Created
….
Course
Renamed
Course
Capacity
Changed
….
Student
Subscribed
to Course
Course: jdsj4 Student:gfh3j ---
Course: jdsj4 Course: jdsj4
---
Course: jdsj4
Student: gfh3j
Pure Events
Tags (Domain Identifiers)
Subscribe
Student to
Course
Command
Subscribe
Student to
Course
Command
Decision based on the following business rules:
- A course cannot accept more than N student
- The student cannot join more than 10 courses
Student
Subscribed
to Course
Event
Subscribe
Student to
Course
Command
Decision based on the following business rules:
- A course cannot accept more than N student
- The student cannot join more than 10 courses
{"StreamQuery": {
"DomainIdentifiers": [
{ "course": "jdsj4..." },
{ "student": "gfh3..." }
], "Types": [
"Course Created",
"Student Created",
"Course Capacity Changed",
"Student Subscribed to Course",
"Student Unsubscribed from Course"]
}}
{"StreamQuery": {
"DomainIdentifiers": [
{ "course": "jdsj4..." },
{ "student": "gfh3..." }
], "Types": [
"Course Created",
"Student Created",
"Course Capacity Changed",
"Student Subscribed to Course",
"Student Unsubscribed from Course"]
}}
Subscribe
Student to
Course
Command
Decision based on the following business rules:
- A course cannot accept more than N student
- The student cannot join more than 10 courses
Course
Created
Student
Created
….
Course
Renamed
Course
Capacity
Changed
….
Course: jdsj4 Student:gfhl3 ---
Course: jdsj4 Course: jdsj4
---
Pure Events
Tags
(Domain Identifiers)
Subscribe
Student to
Course
Command
Decision based on the following business rules:
- A course cannot accept more than N student
- The student cannot join more than 10 courses
Course
Created
Student
Created
….
Course
Renamed
Course
Capacity
Changed
….
Course: jdsj4 Student:gfhl3 ---
Course: jdsj4 Course: jdsj4
---
Pure Events
Tags
(Domain Identifiers)
Student
Subscribed
to Course
Event
Subscribe
Student to
Course
Command
Decision based on the following business rules:
- A course cannot accept more than N student
- The student cannot join more than 10 courses
Course
Created
Student
Created
….
Course
Renamed
Course
Capacity
Changed
….
Course: jdsj4 Student:gfhl3 ---
Course: jdsj4 Course: jdsj4
---
Pure Events
Tags
(Domain Identifiers)
Student
Subscribed
to Course
Course: jdsj4
Student: gfh3
Append Events with Domain Identifiers
append(DomainEvent[] events)
append(DomainEvent[] events, StreamQuery query, EventIdentifier lastEvent)
Domain Event
DomainEvent {
Event event,
DomainIdentifiers[] identifiers
}
Domain Identifier
KEY: VALUE
Domain Identifier
KEY: VALUE
The concept in the domain
Domain Identifier
KEY: VALUE
The concept in the domain The unique instance identifier
Domain Identifier
KEY: VALUE
The concept in the domain The unique instance identifier
This is just an example,
They can be anything, as far as they are unique inside the bounded context
Student
Subscribed
to Course
Event
Subscribe
Student to
Course
Command
Decision based on the following business rules:
- A course cannot accept more than N students
- The student cannot join more than 10 courses
Course
Created
Student
Created
….
Course
Renamed
Course
Capacity
Changed
….
Course: jdsj4 Student:gfh3j ---
Course: jdsj4 Course: jdsj4
---
Pure Events
Tags
(Domain Identifiers)
Student
Subscribed
to Course
Course: jdsj4
Student: gfh3j
Student
Subscribed
to Course
Event
Subscribe
Student to
Course
Command
Decision based on the following business rules:
- A course cannot accept more than N students
- The student cannot join more than 10 courses
Course
Created
Student
Created
….
Course
Renamed
Course
Capacity
Changed
….
Course: jdsj4 Student:gfh3j ---
Course: jdsj4 Course: jdsj4
---
Pure Events
Tags
(Domain Identifiers)
Student
Subscribed
to Course
Course: jdsj4
Student: gfh3j
Course
Fully
Booked
Event
Course Fully
Booked
Course: jdsj4
append(DomainEvent[] events, StreamQuery query, EventIdentifier lastEvent)
append(DomainEvent[] events, StreamQuery query, EventIdentifier lastEvent)
[
Event event = Student subscribed to Course,
DomainIdentifiers[] identifiers = [{course: "jdsj4..."}, {student:"gfh3..."}],
Event event = Course Fully Booked,
DomainIdentifiers[] identifiers = [{course: "jdsj4..."}]
]
append(DomainEvent[] events, StreamQuery query, EventIdentifier lastEvent)
[
Event event = Student subscribed to Course,
DomainIdentifiers[] identifiers = [{course: "jdsj4..."}, {student:"gfh3..."}],
Event event = Course Fully Booked,
DomainIdentifiers[] identifiers = [{course: "jdsj4..."}]
]
DomainIdentifiers: [ {course: "jdsj4..."},
{student:"gfh3..."}],
Types: [ "Course Created", "Student Created", "Course Capacity Changed",
"Student Subscribed to Course", "Student Unsubscribed from Course"]}
append(DomainEvent[] events, StreamQuery query, EventIdentifier lastEvent)
[
Event event = Student subscribed to Course,
DomainIdentifiers[] identifiers = [{course: "jdsj4..."}, {student:"gfh3..."}],
Event event = Course Fully Booked,
DomainIdentifiers[] identifiers = [{course: "jdsj4..."}]
]
DomainIdentifiers: [ {course: "jdsj4..."},
{student:"gfh3..."}],
Types: [ "Course Created", "Student Created", "Course Capacity Changed",
"Student Subscribed to Course", "Student Unsubscribed from Course"]}
...593
Pure events
Pure events
An event does NOT belong to an aggregate
An event is just a description of a fact that is important for the business
An event can be related to one or multiple domain concepts, addressed by their
Domain Identifiers
Pure events
An event does NOT belong to an aggregate
An event is just a description of a fact that is important for the business
An event can be related to one or multiple domain concepts, addressed by their
Domain Identifiers
Pure events
An event does NOT belong to an aggregate
An event is just a description of a fact that is important for the business
An event can be related to one or multiple domain concepts
addressed by their Domain Identifiers
Less complexity
Less complexity
No owner of the event
The business decision can easily involve several domain concepts
The decision is taken in one place
Less complexity
No owner of the event
The business decision can easily involve several domain concepts
The decision is taken in one place
Less complexity
No owner of the event
The business decision can easily involve several domain concepts
The decision is taken in one place
Saga
Subscribe Student to
Course Command
Subscribe Student to
Course Command
Subscribe Student to
Course Command
Student Subscribed
Course Event
Student
Course
revert
Unsubscribe Student
to Course Command
Student Unsubscribed
Course Event
Student
1
1
2
3
More flexibility
Event sourcing provides a huge advantage because it decouples the persistence
from the model needed for taking the decision
Refactoring
● Change the StreamQuery
● Add/Remove Domain Identifiers
More flexibility
Event sourcing provides a huge advantage because it decouples the persistence
from the model needed for taking the decision
Refactoring
● Change the StreamQuery
More flexibility
Event sourcing provides a huge advantage because it decouples the persistence
from the model needed for taking the decision
Refactoring
● Change the StreamQuery
● Add/Remove Domain Identifiers
Dynamic Consistency Boundary - aka DCB
Dynamic Consistency Boundary - aka DCB
● Perfect match with story telling
Dynamic Consistency Boundary - aka DCB
● Perfect match with story telling
● Focus on behaviour instead of model
Dynamic Consistency Boundary - aka DCB
● Perfect match with story telling
● Focus on behaviour instead of model
● Less contention
Dynamic Consistency Boundary - aka DCB
● Perfect match with story telling
● Focus on behaviour instead of model
● Less contention
● Less complexity
Dynamic Consistency Boundary - aka DCB
● Perfect match with story telling
● Focus on behaviour instead of model
● Less contention
● Less complexity
● Simpler to refactor
The aggregate is dead
Long live the aggregate
There is no pattern that can replace common sense.
@_sara_p_
Sara Pellegrini
@MilanSavic14
Milan Savic

More Related Content

What's hot

Domain driven design and model driven development
Domain driven design and model driven developmentDomain driven design and model driven development
Domain driven design and model driven developmentDmitry Geyzersky
 
Domain Driven Design
Domain Driven DesignDomain Driven Design
Domain Driven DesignRyan Riley
 
Domain Driven Design (DDD)
Domain Driven Design (DDD)Domain Driven Design (DDD)
Domain Driven Design (DDD)Tom Kocjan
 
Clean Architecture
Clean ArchitectureClean Architecture
Clean ArchitectureBadoo
 
Domain Driven Design Introduction
Domain Driven Design IntroductionDomain Driven Design Introduction
Domain Driven Design Introductionwojtek_s
 
Clean architecture
Clean architectureClean architecture
Clean architecture.NET Crowd
 
A Practical Guide to Domain Driven Design: Presentation Slides
A Practical Guide to Domain Driven Design: Presentation SlidesA Practical Guide to Domain Driven Design: Presentation Slides
A Practical Guide to Domain Driven Design: Presentation Slidesthinkddd
 
Domain Driven Design: Zero to Hero
Domain Driven Design: Zero to HeroDomain Driven Design: Zero to Hero
Domain Driven Design: Zero to HeroFabrício Rissetto
 
Hexagonal architecture - message-oriented software design
Hexagonal architecture  - message-oriented software designHexagonal architecture  - message-oriented software design
Hexagonal architecture - message-oriented software designMatthias Noback
 
Taming Complex Domains with Domain Driven Design
Taming Complex Domains with Domain Driven DesignTaming Complex Domains with Domain Driven Design
Taming Complex Domains with Domain Driven DesignAlberto Brandolini
 
Best Practices NgRx for Scaling Your Angular Application
Best Practices NgRx  for Scaling Your Angular ApplicationBest Practices NgRx  for Scaling Your Angular Application
Best Practices NgRx for Scaling Your Angular ApplicationVagner Oliveira
 
Implementing DDD with C#
Implementing DDD with C#Implementing DDD with C#
Implementing DDD with C#Pascal Laurin
 
Clean architecture
Clean architectureClean architecture
Clean architectureandbed
 
Design Pattern For C# Part 1
Design Pattern For C# Part 1Design Pattern For C# Part 1
Design Pattern For C# Part 1Shahzad
 
Clean Code I - Best Practices
Clean Code I - Best PracticesClean Code I - Best Practices
Clean Code I - Best PracticesTheo Jungeblut
 
CQRS + Event Sourcing
CQRS + Event SourcingCQRS + Event Sourcing
CQRS + Event SourcingMike Bild
 

What's hot (20)

Domain driven design and model driven development
Domain driven design and model driven developmentDomain driven design and model driven development
Domain driven design and model driven development
 
Domain Driven Design
Domain Driven DesignDomain Driven Design
Domain Driven Design
 
Domain Driven Design (DDD)
Domain Driven Design (DDD)Domain Driven Design (DDD)
Domain Driven Design (DDD)
 
Clean architecture
Clean architectureClean architecture
Clean architecture
 
Clean Architecture
Clean ArchitectureClean Architecture
Clean Architecture
 
Domain Driven Design Introduction
Domain Driven Design IntroductionDomain Driven Design Introduction
Domain Driven Design Introduction
 
Clean architecture
Clean architectureClean architecture
Clean architecture
 
A Practical Guide to Domain Driven Design: Presentation Slides
A Practical Guide to Domain Driven Design: Presentation SlidesA Practical Guide to Domain Driven Design: Presentation Slides
A Practical Guide to Domain Driven Design: Presentation Slides
 
Domain Driven Design: Zero to Hero
Domain Driven Design: Zero to HeroDomain Driven Design: Zero to Hero
Domain Driven Design: Zero to Hero
 
Hexagonal architecture - message-oriented software design
Hexagonal architecture  - message-oriented software designHexagonal architecture  - message-oriented software design
Hexagonal architecture - message-oriented software design
 
Ddd + ah + microservicios
Ddd + ah + microserviciosDdd + ah + microservicios
Ddd + ah + microservicios
 
Domain Driven Design 101
Domain Driven Design 101Domain Driven Design 101
Domain Driven Design 101
 
Taming Complex Domains with Domain Driven Design
Taming Complex Domains with Domain Driven DesignTaming Complex Domains with Domain Driven Design
Taming Complex Domains with Domain Driven Design
 
Best Practices NgRx for Scaling Your Angular Application
Best Practices NgRx  for Scaling Your Angular ApplicationBest Practices NgRx  for Scaling Your Angular Application
Best Practices NgRx for Scaling Your Angular Application
 
Implementing DDD with C#
Implementing DDD with C#Implementing DDD with C#
Implementing DDD with C#
 
Clean coding-practices
Clean coding-practicesClean coding-practices
Clean coding-practices
 
Clean architecture
Clean architectureClean architecture
Clean architecture
 
Design Pattern For C# Part 1
Design Pattern For C# Part 1Design Pattern For C# Part 1
Design Pattern For C# Part 1
 
Clean Code I - Best Practices
Clean Code I - Best PracticesClean Code I - Best Practices
Clean Code I - Best Practices
 
CQRS + Event Sourcing
CQRS + Event SourcingCQRS + Event Sourcing
CQRS + Event Sourcing
 

Similar to The aggregate is dead! Long live the aggregate! - SpringIO.pdf

OOP-Advanced Programming with c++
OOP-Advanced Programming with c++OOP-Advanced Programming with c++
OOP-Advanced Programming with c++Mohamed Essam
 
V Jornadas eMadrid sobre "Educación Digital". Cristina Conati, University of ...
V Jornadas eMadrid sobre "Educación Digital". Cristina Conati, University of ...V Jornadas eMadrid sobre "Educación Digital". Cristina Conati, University of ...
V Jornadas eMadrid sobre "Educación Digital". Cristina Conati, University of ...eMadrid network
 
Multi task learning stepping away from narrow expert models 7.11.18
Multi task learning stepping away from narrow expert models 7.11.18Multi task learning stepping away from narrow expert models 7.11.18
Multi task learning stepping away from narrow expert models 7.11.18Cloudera, Inc.
 
The Google Cloud Adoption Framework
The Google Cloud Adoption FrameworkThe Google Cloud Adoption Framework
The Google Cloud Adoption Frameworkrun_frictionless
 
OOP-Advanced_Programming.pptx
OOP-Advanced_Programming.pptxOOP-Advanced_Programming.pptx
OOP-Advanced_Programming.pptxMohamed Essam
 
Architecture for Flow w/ Wardley Mapping, Domain-Driven Design, and Team Topo...
Architecture for Flow w/ Wardley Mapping, Domain-Driven Design, and Team Topo...Architecture for Flow w/ Wardley Mapping, Domain-Driven Design, and Team Topo...
Architecture for Flow w/ Wardley Mapping, Domain-Driven Design, and Team Topo...Susanne Kaiser
 
Shivani Chouhan ,BCA ,2nd Year
Shivani Chouhan ,BCA ,2nd YearShivani Chouhan ,BCA ,2nd Year
Shivani Chouhan ,BCA ,2nd Yeardezyneecole
 
Bhanu Pratap Singh ,BCA
Bhanu Pratap Singh ,BCA Bhanu Pratap Singh ,BCA
Bhanu Pratap Singh ,BCA dezyneecole
 
Assignment 1. Coretta leases a workshop, in which she weaves rug.docx
Assignment 1. Coretta leases a workshop, in which she weaves rug.docxAssignment 1. Coretta leases a workshop, in which she weaves rug.docx
Assignment 1. Coretta leases a workshop, in which she weaves rug.docxtrippettjettie
 
Microservices Manchester: Microservices and Macro-Economics - A Shorty Histor...
Microservices Manchester: Microservices and Macro-Economics - A Shorty Histor...Microservices Manchester: Microservices and Macro-Economics - A Shorty Histor...
Microservices Manchester: Microservices and Macro-Economics - A Shorty Histor...OpenCredo
 
Nikita Totlani ,BCA 2nd year
Nikita Totlani ,BCA 2nd year Nikita Totlani ,BCA 2nd year
Nikita Totlani ,BCA 2nd year dezyneecole
 
Deepika Mittal,BCA ,2nd Year
Deepika Mittal,BCA ,2nd Year Deepika Mittal,BCA ,2nd Year
Deepika Mittal,BCA ,2nd Year dezyneecole
 
Design patterns - How much we understand and know ??
Design patterns - How much we understand and know ??Design patterns - How much we understand and know ??
Design patterns - How much we understand and know ??Vinay Raj
 

Similar to The aggregate is dead! Long live the aggregate! - SpringIO.pdf (20)

Kill Aggregate
Kill AggregateKill Aggregate
Kill Aggregate
 
OOP-Advanced Programming with c++
OOP-Advanced Programming with c++OOP-Advanced Programming with c++
OOP-Advanced Programming with c++
 
Lecce Presentation2008
Lecce Presentation2008Lecce Presentation2008
Lecce Presentation2008
 
V Jornadas eMadrid sobre "Educación Digital". Cristina Conati, University of ...
V Jornadas eMadrid sobre "Educación Digital". Cristina Conati, University of ...V Jornadas eMadrid sobre "Educación Digital". Cristina Conati, University of ...
V Jornadas eMadrid sobre "Educación Digital". Cristina Conati, University of ...
 
Multi task learning stepping away from narrow expert models 7.11.18
Multi task learning stepping away from narrow expert models 7.11.18Multi task learning stepping away from narrow expert models 7.11.18
Multi task learning stepping away from narrow expert models 7.11.18
 
The Google Cloud Adoption Framework
The Google Cloud Adoption FrameworkThe Google Cloud Adoption Framework
The Google Cloud Adoption Framework
 
OOP-Advanced_Programming.pptx
OOP-Advanced_Programming.pptxOOP-Advanced_Programming.pptx
OOP-Advanced_Programming.pptx
 
Architecture for Flow w/ Wardley Mapping, Domain-Driven Design, and Team Topo...
Architecture for Flow w/ Wardley Mapping, Domain-Driven Design, and Team Topo...Architecture for Flow w/ Wardley Mapping, Domain-Driven Design, and Team Topo...
Architecture for Flow w/ Wardley Mapping, Domain-Driven Design, and Team Topo...
 
Chounta@paws
Chounta@pawsChounta@paws
Chounta@paws
 
Shivani Chouhan ,BCA ,2nd Year
Shivani Chouhan ,BCA ,2nd YearShivani Chouhan ,BCA ,2nd Year
Shivani Chouhan ,BCA ,2nd Year
 
Bhanu Pratap Singh ,BCA
Bhanu Pratap Singh ,BCA Bhanu Pratap Singh ,BCA
Bhanu Pratap Singh ,BCA
 
Assignment 1. Coretta leases a workshop, in which she weaves rug.docx
Assignment 1. Coretta leases a workshop, in which she weaves rug.docxAssignment 1. Coretta leases a workshop, in which she weaves rug.docx
Assignment 1. Coretta leases a workshop, in which she weaves rug.docx
 
Microservices Manchester: Microservices and Macro-Economics - A Shorty Histor...
Microservices Manchester: Microservices and Macro-Economics - A Shorty Histor...Microservices Manchester: Microservices and Macro-Economics - A Shorty Histor...
Microservices Manchester: Microservices and Macro-Economics - A Shorty Histor...
 
Ooad
OoadOoad
Ooad
 
Ooad
OoadOoad
Ooad
 
Oos Short Q N
Oos Short Q NOos Short Q N
Oos Short Q N
 
"Paradigm Shifting" Presentation
"Paradigm Shifting" Presentation"Paradigm Shifting" Presentation
"Paradigm Shifting" Presentation
 
Nikita Totlani ,BCA 2nd year
Nikita Totlani ,BCA 2nd year Nikita Totlani ,BCA 2nd year
Nikita Totlani ,BCA 2nd year
 
Deepika Mittal,BCA ,2nd Year
Deepika Mittal,BCA ,2nd Year Deepika Mittal,BCA ,2nd Year
Deepika Mittal,BCA ,2nd Year
 
Design patterns - How much we understand and know ??
Design patterns - How much we understand and know ??Design patterns - How much we understand and know ??
Design patterns - How much we understand and know ??
 

Recently uploaded

Active Directory Penetration Testing, cionsystems.com.pdf
Active Directory Penetration Testing, cionsystems.com.pdfActive Directory Penetration Testing, cionsystems.com.pdf
Active Directory Penetration Testing, cionsystems.com.pdfCionsystems
 
Test Automation Strategy for Frontend and Backend
Test Automation Strategy for Frontend and BackendTest Automation Strategy for Frontend and Backend
Test Automation Strategy for Frontend and BackendArshad QA
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software DevelopersVinodh Ram
 
DNT_Corporate presentation know about us
DNT_Corporate presentation know about usDNT_Corporate presentation know about us
DNT_Corporate presentation know about usDynamic Netsoft
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxComplianceQuest1
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...harshavardhanraghave
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfkalichargn70th171
 
Clustering techniques data mining book ....
Clustering techniques data mining book ....Clustering techniques data mining book ....
Clustering techniques data mining book ....ShaimaaMohamedGalal
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...panagenda
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfjoe51371421
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...MyIntelliSource, Inc.
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsAndolasoft Inc
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantAxelRicardoTrocheRiq
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxbodapatigopi8531
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionSolGuruz
 

Recently uploaded (20)

Active Directory Penetration Testing, cionsystems.com.pdf
Active Directory Penetration Testing, cionsystems.com.pdfActive Directory Penetration Testing, cionsystems.com.pdf
Active Directory Penetration Testing, cionsystems.com.pdf
 
Test Automation Strategy for Frontend and Backend
Test Automation Strategy for Frontend and BackendTest Automation Strategy for Frontend and Backend
Test Automation Strategy for Frontend and Backend
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software Developers
 
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS LiveVip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
 
DNT_Corporate presentation know about us
DNT_Corporate presentation know about usDNT_Corporate presentation know about us
DNT_Corporate presentation know about us
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docx
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
Clustering techniques data mining book ....
Clustering techniques data mining book ....Clustering techniques data mining book ....
Clustering techniques data mining book ....
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdf
 
Call Girls In Mukherjee Nagar 📱 9999965857 🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
Call Girls In Mukherjee Nagar 📱  9999965857  🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...Call Girls In Mukherjee Nagar 📱  9999965857  🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
Call Girls In Mukherjee Nagar 📱 9999965857 🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.js
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service Consultant
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptx
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with Precision
 
Exploring iOS App Development: Simplifying the Process
Exploring iOS App Development: Simplifying the ProcessExploring iOS App Development: Simplifying the Process
Exploring iOS App Development: Simplifying the Process
 

The aggregate is dead! Long live the aggregate! - SpringIO.pdf