SlideShare a Scribd company logo
1 of 52
Download to read offline
Introduction to Event Sourcing 
… and CQRS
Vladik Khononov 
Solutions Architect at Plexop 
vladikk http://vladikk.com vladikk 
http://il.linkedin.com/in/vladikkhononov/
Introduction to Event Sourcing 
… and CQRS
Domain Driven Design?
Introduction 
How we are used to do things
Business 
Domain 
Model 
Logic 
PresentationDAL
Model: A simplified representation of a system 
or phenomenon. 
– www.dictionary.com 
מודל: ייצוג תאורטי של מערכת מורכבת, שמטרתו 
לחקות את המערכת בהיבטים מהותיים. המודל 
אינו מתאר כל תופעה במערכת, אלא מתייחס 
להיבטים מוגדרים ומצומצמים שלה. המודל 
מבוסס על קירוב של המציאות בדרך של הפשטה, 
איחוד ישויות והתעלמות מגורמים שהשפעתם 
אינה מהותית. 
– www.wikipedia.org
User 
Interface 
Storage 
Domain 
Model
Domain Model
Good Domain Model 
• Not too much 
• Not too less 
• Sweet spot 
• The information we need 
• The information we might need
Why domain models fail 
• We absolutely suck at predicting the future 
• No single model can suit all the use cases 
(e.g.: transactional processing, business intelligence, search) 
• Model transformations are painful
Case Study: 
Customers Management
• A customer has customer id number and a name 
• A customer has contact information: email, phone 
number 
• A customer can be in on of the following states: 
New, CallLater, Converted, NotInterested 
• A seller has seller id number, name and password 
• The selling home page contains a list of the 
customers in the following statuses: 
• New 
• CallLater (when scheduled call date is met)
• Seller chooses a customer to call from the home 
page 
• Seller can change the customer’s status to 
“Converted”, “Not Interested” 
• Seller can schedule a future call by setting the 
future call date. The Customer’s status will change 
to “CallLater” 
• Seller can change name, email, and phone number
enum Status { 
New, CallLater, Converted, 
NotInterested 
} 
class Customer { 
int Id; 
string Name; 
Status Status; 
DateTime? ScheduledCall; 
string Email; 
string PhoneNumber; 
} 
CREATE TABLE Customers ( 
ID INTEGER, 
Name CHAR(40), 
Email CHAR(40), 
PhoneNumber CHAR(40), 
Status INTEGER, 
ScheduledCall DATETIME, 
PRIMARY KEY (ID) 
) 
class Seller { 
int Id; 
string Name; 
string Password; 
} 
CREATE TABLE Sellers ( 
ID INTEGER, 
Name CHAR(40), 
Password CHAR(40) 
PRIMARY KEY (ID) 
)
• Seller can find customers by name, email, and/or 
phone number in the search page 
• The customers should be found by the current and 
the past values
• If no new customers are available on the home 
page, it should display customers in the 
NotInterested status, if it was set more than a 30 
days ago
• Analysts should be able to review status changes 
history for each customer - change date and the 
new status
class Seller { 
int Id; 
string Name; 
string Password; 
} 
CREATE TABLE Sellers ( 
ID INTEGER, 
Name CHAR(40), 
Password CHAR(40) 
PRIMARY KEY (ID) 
) 
enum Status { 
New, CallLater, Converted, 
NotInterested 
} 
class Customer { 
int Id; 
string Name; 
Status Status; 
DateTime? ScheduledCall; 
string Email; 
string PhoneNumber; 
} 
CREATE TABLE Customers ( 
ID INTEGER, 
Name CHAR(40), 
Email CHAR(40), 
PhoneNumber CHAR(40), 
Status INTEGER, 
ScheduledCall DATETIME, 
PRIMARY KEY (ID) 
)
Id Name Email Phone number Status 
Scheduled 
Call 
10 John john@gmail.com 04-2342343 New
Id Name Email Phone number Status 
Scheduled 
Call 
10 John john@gmail.com 04-2342343 CallLater 27/10/2014
Id Name Email Phone number Status 
Scheduled 
Call 
10 John john@gmail.com 08-9876653 CallLater 27/10/2014
Id Name Email Phone number Status 
Scheduled 
Call 
10 John john@gmail.com 08-9876653 Converted
Id Name Email Phone number Status 
Scheduled 
Call 
10 John john@gmail.com 08-9876653 Converted
Event Sourcing 
Capture all changes to an application 
state as a sequence of events 
~ Martin Fowler
class StatusChanged : IEvent { 
Status NewStatus; 
DateTime CreatedOn; int CreatedBy; 
} 
class FutureCallScheduled : IEvent { 
DateTime ScheduledCallTime; 
DateTime CreatedOn; int CreatedBy; 
} 
class ContactDetailsWereUpdated : IEvent { 
string NewName; 
string NewEmail; 
string NewPhone; 
DateTime CreatedOn; int CreatedBy; 
}
class Customer { 
int Id; 
string Name; 
string Email; 
string PhoneNumber; 
Status Status; 
DateTime? ScheduledCall; 
List<IEvent> Events; 
… 
void Apply(StatusChanged e) { 
Status = e.NewStatus; 
Events.Add(e); 
} 
…. 
…. 
}
class Customer { 
int Id; 
string Name; 
string Email; 
string PhoneNumber; 
Status Status; 
DateTime? ScheduledCall; 
List<IEvent> Events; 
… 
… 
void Apply(FutureCallScheduled e) { 
ScheduledCall = e.ScheduledCallTime; 
Events.Add(e); 
} 
… 
}
class Customer { 
int Id; 
string Name; 
string Email; 
string PhoneNumber; 
Status Status; 
DateTime? ScheduledCall; 
List<IEvent> Events; 
… 
… 
… 
void Apply(ContactDetailsWereUpdated e) { 
Name = e.NewName; 
Email = e.NewEmail; 
PhoneNumber = e.NewPhoneNumber; 
Events.Add(e); 
} 
}
Id Name Email Phone number Status 
Scheduled 
Call 
10 John john@gmail.com 08-9876653 Converted
1. new StatusChanged(Status.CallLater) 
2. new FutureCallScheduled(’27/10/2014’) 
3. new ContactDetailsWereUpdated( 
NewPhoneNumber=’08-9876653’ 
) 
4. new StatusChanged(Status.Converted)
Event Storage 
Entity Id + New events 
Event1, Entity Id 
Event2, 
Event3, 
….
class CustomerSearchModel { 
int Id; 
List<string> Names; 
List<string> Emails; 
List<string> PhoneNumbers; 
Status Status; 
DateTime? ScheduledCall; 
… 
… 
… 
void Apply(ContactDetailsWereUpdated e) { 
Names.Add(e.NewName); 
Emails.Add(e.NewEmail); 
PhoneNumbers.Add(e.NewPhoneNumber); 
} 
}
class CustomerAnalysisModel { 
int Id; 
string Name; 
string Email; 
string PhoneNumber; 
List<StatusChange> StatusChanges; 
DateTime? ScheduledCall; 
… 
void Apply(StatusChanged e) { 
StatusChanges.Add( 
new StatusChange(e.CreatedOn, e.NewStatus) 
); 
} 
…. 
…. 
}
class Customer { 
int Id; 
string Name; 
string Email; 
string PhoneNumber; 
Status Status; 
DateTime? ScheduledCall; 
List<IEvent> Events; 
}
class CustomerSearchModel { 
int Id; 
List<string> Names; 
List<string> Emails; 
List<string> PhoneNumbers; 
Status Status; 
DateTime? ScheduledCall; 
}
class CustomerAnalysisModel { 
int Id; 
string Name; 
string Email; 
string PhoneNumber; 
List<StatusChange> StatusChanges; 
DateTime? ScheduledCall; 
}
Good Domain Model 
✓ Not too much 
✓ Not too less 
✓ Sweet spot 
✓ The information we need 
✓ The information we might need
Why domain models fail 
✓ We absolutely suck at predicting the future 
✓ No single model can suit all the use cases 
(e.g.: transactional processing, business intelligence, search) 
✓ Model transformations are painful
Event Storage 
Entity Id + New events 
Event1, Entity Id 
Event2, 
Event3, 
….
CQRS 
Command Query Responsibility Segregation
Layered Architecture
Step 1
Step 2
Step 3
CQRS
Conclusions 
• Event based models 
• Effective modeling 
• No future predicting required 
• Time machine 
• Retroactive debugging 
• Infrastructural freedom 
• Infinite scalability 
• Easy to scale writes 
• Easy to scale reads
Before you try this at home 
• Read “Implementing Domain Driven Design” by 
Vaughn Vernon 
• Read “Domain Driven Design” by Eric Evans 
• Follow Greg Young 
• Read DDD/CQRS on Google Groups
Questions?
http://vladikk.com 
http://twitter.com/vladikk 
http://facebook.com/vladikk 
http://il.linkedin.com/in/vladikkhononov

More Related Content

Similar to Introduction to Event Sourcing and CQRS

Intro to AppExchange - Building Composite Apps
Intro to AppExchange - Building Composite AppsIntro to AppExchange - Building Composite Apps
Intro to AppExchange - Building Composite Apps
dreamforce2006
 
Performance Tuning for Visualforce and Apex
Performance Tuning for Visualforce and ApexPerformance Tuning for Visualforce and Apex
Performance Tuning for Visualforce and Apex
Salesforce Developers
 
14147503 Intentions Interfaces Making Patterns Concrete
14147503 Intentions Interfaces Making Patterns Concrete14147503 Intentions Interfaces Making Patterns Concrete
14147503 Intentions Interfaces Making Patterns Concrete
QConLondon2008
 
Udi Dahan Intentions And Interfaces
Udi Dahan Intentions And InterfacesUdi Dahan Intentions And Interfaces
Udi Dahan Intentions And Interfaces
deimos
 

Similar to Introduction to Event Sourcing and CQRS (20)

Service Architecture patterns
Service Architecture patternsService Architecture patterns
Service Architecture patterns
 
Apex Design Patterns
Apex Design PatternsApex Design Patterns
Apex Design Patterns
 
Lerman Vvs14 Ef Tips And Tricks
Lerman Vvs14  Ef Tips And TricksLerman Vvs14  Ef Tips And Tricks
Lerman Vvs14 Ef Tips And Tricks
 
Atl elevate programmatic developer slides
Atl elevate programmatic developer slidesAtl elevate programmatic developer slides
Atl elevate programmatic developer slides
 
Intro to AppExchange - Building Composite Apps
Intro to AppExchange - Building Composite AppsIntro to AppExchange - Building Composite Apps
Intro to AppExchange - Building Composite Apps
 
Programming Building Blocks for Admins
Programming Building Blocks for Admins Programming Building Blocks for Admins
Programming Building Blocks for Admins
 
LINQ
LINQLINQ
LINQ
 
Apex Design Patterns
Apex Design PatternsApex Design Patterns
Apex Design Patterns
 
Performance Tuning for Visualforce and Apex
Performance Tuning for Visualforce and ApexPerformance Tuning for Visualforce and Apex
Performance Tuning for Visualforce and Apex
 
ADBMS ASSIGNMENT
ADBMS ASSIGNMENTADBMS ASSIGNMENT
ADBMS ASSIGNMENT
 
14147503 Intentions Interfaces Making Patterns Concrete
14147503 Intentions Interfaces Making Patterns Concrete14147503 Intentions Interfaces Making Patterns Concrete
14147503 Intentions Interfaces Making Patterns Concrete
 
WSO2 Complex Event Processor
WSO2 Complex Event ProcessorWSO2 Complex Event Processor
WSO2 Complex Event Processor
 
Ralf Laemmel - Not quite a sales pitch for C# 3.0 and .NET's LINQ - 2008-03-05
Ralf Laemmel - Not quite a sales pitch for C# 3.0 and .NET's LINQ - 2008-03-05Ralf Laemmel - Not quite a sales pitch for C# 3.0 and .NET's LINQ - 2008-03-05
Ralf Laemmel - Not quite a sales pitch for C# 3.0 and .NET's LINQ - 2008-03-05
 
10.Local Database & LINQ
10.Local Database & LINQ10.Local Database & LINQ
10.Local Database & LINQ
 
Df12 Performance Tuning
Df12 Performance TuningDf12 Performance Tuning
Df12 Performance Tuning
 
Udi Dahan Intentions And Interfaces
Udi Dahan Intentions And InterfacesUdi Dahan Intentions And Interfaces
Udi Dahan Intentions And Interfaces
 
ADO.NET Entity Framework by Jose A. Blakeley and Michael Pizzo
ADO.NET Entity Framework by Jose A. Blakeley and Michael PizzoADO.NET Entity Framework by Jose A. Blakeley and Michael Pizzo
ADO.NET Entity Framework by Jose A. Blakeley and Michael Pizzo
 
Domain Driven Design 101
Domain Driven Design 101Domain Driven Design 101
Domain Driven Design 101
 
Database Project of a Corporation or Firm
Database Project of a Corporation or Firm Database Project of a Corporation or Firm
Database Project of a Corporation or Firm
 
SOQL & SOSL for Admins
SOQL & SOSL for AdminsSOQL & SOSL for Admins
SOQL & SOSL for Admins
 

More from Vladik Khononov

Introduction to CQRS and DDDD
Introduction to CQRS and DDDDIntroduction to CQRS and DDDD
Introduction to CQRS and DDDD
Vladik Khononov
 
Internal Project: Under the Hood
Internal Project: Under the HoodInternal Project: Under the Hood
Internal Project: Under the Hood
Vladik Khononov
 

More from Vladik Khononov (7)

7 Years of DDD: Tackling Complexity in Marketing Systems (DDD Europe 2018)
7 Years of DDD: Tackling Complexity in Marketing Systems (DDD Europe 2018)7 Years of DDD: Tackling Complexity in Marketing Systems (DDD Europe 2018)
7 Years of DDD: Tackling Complexity in Marketing Systems (DDD Europe 2018)
 
How to Tame TDD - ISTA 2017
How to Tame TDD - ISTA 2017How to Tame TDD - ISTA 2017
How to Tame TDD - ISTA 2017
 
ISTA 2016: Event Sourcing
ISTA 2016: Event SourcingISTA 2016: Event Sourcing
ISTA 2016: Event Sourcing
 
Mind Your Business. And Its Logic
Mind Your Business. And Its LogicMind Your Business. And Its Logic
Mind Your Business. And Its Logic
 
Introduction to MongoDB
Introduction to MongoDBIntroduction to MongoDB
Introduction to MongoDB
 
Introduction to CQRS and DDDD
Introduction to CQRS and DDDDIntroduction to CQRS and DDDD
Introduction to CQRS and DDDD
 
Internal Project: Under the Hood
Internal Project: Under the HoodInternal Project: Under the Hood
Internal Project: Under the Hood
 

Recently uploaded

Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
WSO2
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
?#DUbAI#??##{{(☎️+971_581248768%)**%*]'#abortion pills for sale in dubai@
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Victor Rentea
 

Recently uploaded (20)

Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKSpring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
CNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In PakistanCNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In Pakistan
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 

Introduction to Event Sourcing and CQRS

  • 1. Introduction to Event Sourcing … and CQRS
  • 2. Vladik Khononov Solutions Architect at Plexop vladikk http://vladikk.com vladikk http://il.linkedin.com/in/vladikkhononov/
  • 3. Introduction to Event Sourcing … and CQRS
  • 5.
  • 6. Introduction How we are used to do things
  • 7. Business Domain Model Logic PresentationDAL
  • 8. Model: A simplified representation of a system or phenomenon. – www.dictionary.com מודל: ייצוג תאורטי של מערכת מורכבת, שמטרתו לחקות את המערכת בהיבטים מהותיים. המודל אינו מתאר כל תופעה במערכת, אלא מתייחס להיבטים מוגדרים ומצומצמים שלה. המודל מבוסס על קירוב של המציאות בדרך של הפשטה, איחוד ישויות והתעלמות מגורמים שהשפעתם אינה מהותית. – www.wikipedia.org
  • 9. User Interface Storage Domain Model
  • 11. Good Domain Model • Not too much • Not too less • Sweet spot • The information we need • The information we might need
  • 12. Why domain models fail • We absolutely suck at predicting the future • No single model can suit all the use cases (e.g.: transactional processing, business intelligence, search) • Model transformations are painful
  • 13. Case Study: Customers Management
  • 14. • A customer has customer id number and a name • A customer has contact information: email, phone number • A customer can be in on of the following states: New, CallLater, Converted, NotInterested • A seller has seller id number, name and password • The selling home page contains a list of the customers in the following statuses: • New • CallLater (when scheduled call date is met)
  • 15. • Seller chooses a customer to call from the home page • Seller can change the customer’s status to “Converted”, “Not Interested” • Seller can schedule a future call by setting the future call date. The Customer’s status will change to “CallLater” • Seller can change name, email, and phone number
  • 16. enum Status { New, CallLater, Converted, NotInterested } class Customer { int Id; string Name; Status Status; DateTime? ScheduledCall; string Email; string PhoneNumber; } CREATE TABLE Customers ( ID INTEGER, Name CHAR(40), Email CHAR(40), PhoneNumber CHAR(40), Status INTEGER, ScheduledCall DATETIME, PRIMARY KEY (ID) ) class Seller { int Id; string Name; string Password; } CREATE TABLE Sellers ( ID INTEGER, Name CHAR(40), Password CHAR(40) PRIMARY KEY (ID) )
  • 17. • Seller can find customers by name, email, and/or phone number in the search page • The customers should be found by the current and the past values
  • 18. • If no new customers are available on the home page, it should display customers in the NotInterested status, if it was set more than a 30 days ago
  • 19. • Analysts should be able to review status changes history for each customer - change date and the new status
  • 20. class Seller { int Id; string Name; string Password; } CREATE TABLE Sellers ( ID INTEGER, Name CHAR(40), Password CHAR(40) PRIMARY KEY (ID) ) enum Status { New, CallLater, Converted, NotInterested } class Customer { int Id; string Name; Status Status; DateTime? ScheduledCall; string Email; string PhoneNumber; } CREATE TABLE Customers ( ID INTEGER, Name CHAR(40), Email CHAR(40), PhoneNumber CHAR(40), Status INTEGER, ScheduledCall DATETIME, PRIMARY KEY (ID) )
  • 21. Id Name Email Phone number Status Scheduled Call 10 John john@gmail.com 04-2342343 New
  • 22. Id Name Email Phone number Status Scheduled Call 10 John john@gmail.com 04-2342343 CallLater 27/10/2014
  • 23. Id Name Email Phone number Status Scheduled Call 10 John john@gmail.com 08-9876653 CallLater 27/10/2014
  • 24. Id Name Email Phone number Status Scheduled Call 10 John john@gmail.com 08-9876653 Converted
  • 25. Id Name Email Phone number Status Scheduled Call 10 John john@gmail.com 08-9876653 Converted
  • 26. Event Sourcing Capture all changes to an application state as a sequence of events ~ Martin Fowler
  • 27.
  • 28. class StatusChanged : IEvent { Status NewStatus; DateTime CreatedOn; int CreatedBy; } class FutureCallScheduled : IEvent { DateTime ScheduledCallTime; DateTime CreatedOn; int CreatedBy; } class ContactDetailsWereUpdated : IEvent { string NewName; string NewEmail; string NewPhone; DateTime CreatedOn; int CreatedBy; }
  • 29. class Customer { int Id; string Name; string Email; string PhoneNumber; Status Status; DateTime? ScheduledCall; List<IEvent> Events; … void Apply(StatusChanged e) { Status = e.NewStatus; Events.Add(e); } …. …. }
  • 30. class Customer { int Id; string Name; string Email; string PhoneNumber; Status Status; DateTime? ScheduledCall; List<IEvent> Events; … … void Apply(FutureCallScheduled e) { ScheduledCall = e.ScheduledCallTime; Events.Add(e); } … }
  • 31. class Customer { int Id; string Name; string Email; string PhoneNumber; Status Status; DateTime? ScheduledCall; List<IEvent> Events; … … … void Apply(ContactDetailsWereUpdated e) { Name = e.NewName; Email = e.NewEmail; PhoneNumber = e.NewPhoneNumber; Events.Add(e); } }
  • 32. Id Name Email Phone number Status Scheduled Call 10 John john@gmail.com 08-9876653 Converted
  • 33. 1. new StatusChanged(Status.CallLater) 2. new FutureCallScheduled(’27/10/2014’) 3. new ContactDetailsWereUpdated( NewPhoneNumber=’08-9876653’ ) 4. new StatusChanged(Status.Converted)
  • 34. Event Storage Entity Id + New events Event1, Entity Id Event2, Event3, ….
  • 35. class CustomerSearchModel { int Id; List<string> Names; List<string> Emails; List<string> PhoneNumbers; Status Status; DateTime? ScheduledCall; … … … void Apply(ContactDetailsWereUpdated e) { Names.Add(e.NewName); Emails.Add(e.NewEmail); PhoneNumbers.Add(e.NewPhoneNumber); } }
  • 36. class CustomerAnalysisModel { int Id; string Name; string Email; string PhoneNumber; List<StatusChange> StatusChanges; DateTime? ScheduledCall; … void Apply(StatusChanged e) { StatusChanges.Add( new StatusChange(e.CreatedOn, e.NewStatus) ); } …. …. }
  • 37. class Customer { int Id; string Name; string Email; string PhoneNumber; Status Status; DateTime? ScheduledCall; List<IEvent> Events; }
  • 38. class CustomerSearchModel { int Id; List<string> Names; List<string> Emails; List<string> PhoneNumbers; Status Status; DateTime? ScheduledCall; }
  • 39. class CustomerAnalysisModel { int Id; string Name; string Email; string PhoneNumber; List<StatusChange> StatusChanges; DateTime? ScheduledCall; }
  • 40. Good Domain Model ✓ Not too much ✓ Not too less ✓ Sweet spot ✓ The information we need ✓ The information we might need
  • 41. Why domain models fail ✓ We absolutely suck at predicting the future ✓ No single model can suit all the use cases (e.g.: transactional processing, business intelligence, search) ✓ Model transformations are painful
  • 42. Event Storage Entity Id + New events Event1, Entity Id Event2, Event3, ….
  • 43. CQRS Command Query Responsibility Segregation
  • 48. CQRS
  • 49. Conclusions • Event based models • Effective modeling • No future predicting required • Time machine • Retroactive debugging • Infrastructural freedom • Infinite scalability • Easy to scale writes • Easy to scale reads
  • 50. Before you try this at home • Read “Implementing Domain Driven Design” by Vaughn Vernon • Read “Domain Driven Design” by Eric Evans • Follow Greg Young • Read DDD/CQRS on Google Groups