Loosely Coupled Complexity - Unleash the power of your Domain Model with Command Query Responsibility Segregation and Event Sourcing
Upcoming SlideShare
Loading in...5
×

Like this? Share it with your network

Share

Loosely Coupled Complexity - Unleash the power of your Domain Model with Command Query Responsibility Segregation and Event Sourcing

  • 12,372 views
Uploaded on

Commented slides for the NHibernate day 2010 Presentaion

Commented slides for the NHibernate day 2010 Presentaion

More in: Technology , Business
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
No Downloads

Views

Total Views
12,372
On Slideshare
6,950
From Embeds
5,422
Number of Embeds
47

Actions

Shares
Downloads
212
Comments
1
Likes
16

Embeds 5,422

http://ziobrando.blogspot.com 2,374
http://ziobrando.blogspot.it 1,508
http://ziobrando.blogspot.co.uk 264
http://ziobrando.blogspot.be 257
http://ziobrando.blogspot.de 156
http://feeds.feedburner.com 139
http://ziobrando.blogspot.fr 85
http://ziobrando.blogspot.ch 81
http://lanyrd.com 71
http://domaincoder.blogspot.com 56
http://ziobrando.blogspot.com.au 47
http://ziobrando.blogspot.nl 40
http://ziobrando.blogspot.com.es 39
http://ziobrando.blogspot.com.br 27
http://ziobrando.blogspot.ca 26
http://localhost 22
http://ziobrando.blogspot.no 20
http://ziobrando.blogspot.com.tr 19
http://ziobrando.blogspot.se 19
http://ziobrando.blogspot.in 17
http://ziobrando.blogspot.ie 13
http://ziobrando.blogspot.cz 13
http://ziobrando.blogspot.ru 12
http://ziobrando.blogspot.co.at 10
http://www.ziobrando.blogspot.it 10
http://theoldreader.com 9
http://ziobrando.blogspot.ro 9
http://ziobrando.blogspot.dk 9
http://ziobrando.blogspot.com.ar 8
http://ziobrando.blogspot.co.nz 8
http://domaincoder.blogspot.it 7
http://ziobrando.blogspot.gr 5
http://ziobrando.blogspot.pt 5
http://www.ziobrando.blogspot.com 5
http://ziobrando.blogspot.mx 5
http://ziobrando.blogspot.jp 5
http://ziobrando.blogspot.hu 4
http://ziobrando.blogspot.fi 4
http://translate.googleusercontent.com 3
http://webcache.googleusercontent.com 3
http://ziobrando.blogspot.sg 2
http://ziobrando.blogspot.co.il 1
http://ziobrando.blogspot.sk 1
http://ziobrando.blogspot.hk 1
https://domaincoder.blogspot.com 1
http://a0.twimg.com 1
http://131.253.14.250 1

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide
  • <br />
  • <br />
  • And that&#x2019;s the company I started one year ago. <br />
  • Disclaimer: this is second-hand talk. 99% of the ideas come from these three guys. <br /> In the last couple of years a little revolution has being going on in the DDD community: Udi Dahan (left) and Greg Young (right) have brought new ideas in the DDD landscape. <br />
  • Ok, let&apos;s start from a familiar architecture, what&apos;s wrong with that? <br />
  • <br />
  • Ok, if that&#x2019;s the answer... If you really like that and think that&#x2019;s the best possible world... then I don&#x2019;t have so much to tell you. <br />
  • On the other hand, if you really think about it, there are a few things in your familiar architecture that you&#x2019;ve been probably too used to. Enough to forget that there might be a different way. <br />
  • Let&#x2019;s try again, with a clear mind. <br />
  • <br />
  • Here are some of the things we might not like. <br />
  • Here are some of the things we might not like. <br />
  • Here are some of the things we might not like. <br />
  • Here are some of the things we might not like. <br />
  • Here are some of the things we might not like. <br />
  • Here are some of the things we might not like. <br />
  • And here are some of the questions we might ask ourselves <br />
  • And here are some of the questions we might ask ourselves <br />
  • And here are some of the questions we might ask ourselves <br />
  • And here are some of the questions we might ask ourselves <br />
  • And here are some of the questions we might ask ourselves <br />
  • And here are some of the questions we might ask ourselves <br />
  • Ok, let&#x2019;s start from the anaemic domain model: in the picture red is where the logic is. As you might see, there&#x2019;s not so mouch in the Order class... <br />
  • How did we get there? Well sometimes it&#x2019;s just a matter of features that came for free, like a tool that allows you to reverse engineering your database to create domain classes. <br />
  • Ok, but anaemic domain model is probably the dominant pattern throughout the world, so it must have some advantages: let&#x2019;s dig into them. <br />
  • Ok, but anaemic domain model is probably the dominant pattern throughout the world, so it must have some advantages: let&#x2019;s dig into them. <br />
  • Ok, but anaemic domain model is probably the dominant pattern throughout the world, so it must have some advantages: let&#x2019;s dig into them. <br />
  • Let&#x2019;s look at the drawbacks instead... in two words it provides all the architetural complexity of an OOP system with the advantages in maintenance of a procedural one. :-P <br />
  • Let&#x2019;s look at the drawbacks instead... in two words it provides all the architetural complexity of an OOP system with the advantages in maintenance of a procedural one. :-P <br />
  • Let&#x2019;s look at the drawbacks instead... in two words it provides all the architetural complexity of an OOP system with the advantages in maintenance of a procedural one. :-P <br />
  • Let&#x2019;s look at the drawbacks instead... in two words it provides all the architetural complexity of an OOP system with the advantages in maintenance of a procedural one. :-P <br />
  • So what should we do instead? <br />
  • So what should we do instead? <br />
  • So what should we do instead? <br />
  • So what should we do instead? <br />
  • So what should we do instead? <br />
  • So what should we do instead? <br />
  • So what should we do instead? <br />
  • So what should we do instead? <br />
  • I think this is a really sensible resolution :-) <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • ... you got the point ;-) <br /> Let&#x2019;s try to be a little more constructive <br />
  • For example, Mr. Eric Evans has something really interesting to say about how should we implement a Domain Model: <br />
  • For example, Mr. Eric Evans has something really interesting to say about how should we implement a Domain Model: <br />
  • For example, Mr. Eric Evans has something really interesting to say about how should we implement a Domain Model: <br />
  • For example, Mr. Eric Evans has something really interesting to say about how should we implement a Domain Model: <br />
  • For example, Mr. Eric Evans has something really interesting to say about how should we implement a Domain Model: <br />
  • What does it mean to &#x201C;put behaviour in the domain model&#x201D;? Here is our starting point: all the logic is in the service class. <br />
  • In a &#x201C;Rich&#x201D; Domain Model (I really don&#x2019;t know why is Rich vs Anaemic, maybe &#x201C;bloody domain model&#x201D; or &#x201C;poor domain model&#x201D; weren&#x2019;t ok for the job) le logic is &#x201C;where it belongs&#x201D; according to Single Responsibility Principle (Martin) or Information Expert (Larman). <br /> <br /> It&#x2019;s not spread equally... Customer doesn&#x2019;t do much, while Money for example looks like a pure data type, but has a lot of math-related behaviour in it. <br />
  • Interestingly, TDD and DDD form a perfect match: DDD needs TDD for many of the key practices, while TDD naturally enforces DDD-like coding styles. <br /> It&#x2019;s just perfect. <br />
  • The next key DDD building block is Aggregates. The Domain Model isn&#x2019;t flat. Some links are stronger than others (and UML doesn&#x2019;t really help much in rendering it). <br /> <br /> If we start considering consistency and behaviour as the primary drivers for modeling our domain we&#x2019;ll end up with something quite different from a 1-1 projection of the data model. <br />
  • The next key DDD building block is Aggregates. The Domain Model isn&#x2019;t flat. Some links are stronger than others (and UML doesn&#x2019;t really help much in rendering it). <br /> <br /> If we start considering consistency and behaviour as the primary drivers for modeling our domain we&#x2019;ll end up with something quite different from a 1-1 projection of the data model. <br />
  • For example, in this case we&#x2019;ll notice some duplication, related to customer. But lifecycles of the customer and of the order are different. If a customer moves, we don&#x2019;t want to have all of our past orders changed, at the same time if an order needs to be canceled, we don&#x2019;t want the user to get down the sink as well. <br /> A little duplication is what allows aggregate lifecycles to be independent. <br />
  • Some data-driven analyst are probably really good in spotting these problems just out of their experience. <br />
  • But really, this part of modeling is our everyday work, and should be easy as walking back home in a sunny day. <br />
  • Shouldn&#x2019;t really have to rely on the experience of some rarely available guy that knows all the traps and hidden perils of data modeling. <br />
  • But here&#x2019;s something to think about: this modeling style enforces loose coupling between aggregates. As a side effect, queries tend to be a lot simpler and focused. In many situations, this opens the door for some alternative persistence strategy. <br />
  • Ok, so let&#x2019;s see how DDD can improve our application architecture. <br />
  • Not so many things are happening at the service layer, just basic coordination. <br /> Bounded contexts are enforced, and aggregate boundaries within them. <br /> But other portions of the architecture don&#x2019;t change that much. <br /> <br /> ... is there anything else that we can do? <br />
  • Not so many things are happening at the service layer, just basic coordination. <br /> Bounded contexts are enforced, and aggregate boundaries within them. <br /> But other portions of the architecture don&#x2019;t change that much. <br /> <br /> ... is there anything else that we can do? <br />
  • Not so many things are happening at the service layer, just basic coordination. <br /> Bounded contexts are enforced, and aggregate boundaries within them. <br /> But other portions of the architecture don&#x2019;t change that much. <br /> <br /> ... is there anything else that we can do? <br />
  • Not so many things are happening at the service layer, just basic coordination. <br /> Bounded contexts are enforced, and aggregate boundaries within them. <br /> But other portions of the architecture don&#x2019;t change that much. <br /> <br /> ... is there anything else that we can do? <br />
  • Not so many things are happening at the service layer, just basic coordination. <br /> Bounded contexts are enforced, and aggregate boundaries within them. <br /> But other portions of the architecture don&#x2019;t change that much. <br /> <br /> ... is there anything else that we can do? <br />
  • Not so many things are happening at the service layer, just basic coordination. <br /> Bounded contexts are enforced, and aggregate boundaries within them. <br /> But other portions of the architecture don&#x2019;t change that much. <br /> <br /> ... is there anything else that we can do? <br />
  • Using DO in the UI seemed like a good idea (I confess I hated the abuse of DTOs so much that I tried it myself), but then you run into objects which are potentially inconsistent. <br /> <br /> A common solution is to have every DO in 2 possible states: valid and invalid, and valid state must be enforced before any business method is invoked on the object. So why not make it mandatory, with aspects or template method pattern. Why not make this solution available/mandatory to all the domain classes? ... well ...No. <br />
  • Using DO in the UI seemed like a good idea (I confess I hated the abuse of DTOs so much that I tried it myself), but then you run into objects which are potentially inconsistent. <br /> <br /> A common solution is to have every DO in 2 possible states: valid and invalid, and valid state must be enforced before any business method is invoked on the object. So why not make it mandatory, with aspects or template method pattern. Why not make this solution available/mandatory to all the domain classes? ... well ...No. <br />
  • Using DO in the UI seemed like a good idea (I confess I hated the abuse of DTOs so much that I tried it myself), but then you run into objects which are potentially inconsistent. <br /> <br /> A common solution is to have every DO in 2 possible states: valid and invalid, and valid state must be enforced before any business method is invoked on the object. So why not make it mandatory, with aspects or template method pattern. Why not make this solution available/mandatory to all the domain classes? ... well ...No. <br />
  • Using DO in the UI seemed like a good idea (I confess I hated the abuse of DTOs so much that I tried it myself), but then you run into objects which are potentially inconsistent. <br /> <br /> A common solution is to have every DO in 2 possible states: valid and invalid, and valid state must be enforced before any business method is invoked on the object. So why not make it mandatory, with aspects or template method pattern. Why not make this solution available/mandatory to all the domain classes? ... well ...No. <br />
  • Using DO in the UI seemed like a good idea (I confess I hated the abuse of DTOs so much that I tried it myself), but then you run into objects which are potentially inconsistent. <br /> <br /> A common solution is to have every DO in 2 possible states: valid and invalid, and valid state must be enforced before any business method is invoked on the object. So why not make it mandatory, with aspects or template method pattern. Why not make this solution available/mandatory to all the domain classes? ... well ...No. <br />
  • Using DO in the UI seemed like a good idea (I confess I hated the abuse of DTOs so much that I tried it myself), but then you run into objects which are potentially inconsistent. <br /> <br /> A common solution is to have every DO in 2 possible states: valid and invalid, and valid state must be enforced before any business method is invoked on the object. So why not make it mandatory, with aspects or template method pattern. Why not make this solution available/mandatory to all the domain classes? ... well ...No. <br />
  • Ok, question for the audience: two Stories, hitting different portions of the application, triggered by the same external event. <br /> <br /> How would you model them? I must admit that in a similar situation I spent some time wondering: &#x201C;Is it better to have order.purchase(customer, ...) or customer.purchase(order, ...)?&#x201D; or many other variation on the theme. <br />
  • <br />
  • That&#x2019;s the very specific Greg Young&#x2019;s definition. I like it. <br />
  • Domain Events as a communication means between aggregates really simplify things a lot, even at the conceptual level. <br /> - Do they really belong to the same transaction? <br /> - Would you want the order to roll-bak if you are unable to process the discount for the next order bu the same customer? <br /> <br /> ... but really, how the two things should be related, is a business choice! We just have more and more possibilites in our arsenal. <br />
  • There&#x2019;s been a never ending debate in the SOA community (and many dollars and euros wasted) about &#x201C;service granularity&#x201D;. A good read of the blue book could have helped a lot, the solution was already there... <br />
  • Let&#x2019;s start to bite something bigger <br />
  • Which one is the right shoe for you? <br /> Well ...it depends :-) each one serves a particular use. We change shoes according to what we want to do. <br /> <br /> <br />
  • So why should we have only one architecture? <br />
  • CQS existed before DDD and was part of the DDD toolkit collection, basically at the class design level. It really enhances scalability and maintainability. <br />
  • But CQRS promotes the same concept at the architectural level. Commands and quesries have different needs. <br />
  • When we ask, there is generally no behavior involved. Just data. <br />
  • So one first step might be to evolve the &#x201C;classical&#x201D; DDD architecture... <br />
  • ... into something more specialized: the domain model is used only in the command side, while the query side is definitely thinner. <br />
  • <br />
  • Let&#x2019;s dive into the query side. Udi Dahan pointed out that sometimes the biggest source of optimization is to have a look at what the users are really doing: capturing user intent might surprise you. <br />
  • Also, the fact that we can sometimes provide real time data, doesn&#x2019;t really mean that we must alway provide them. Most of the time a little of delay is absolutely acceptable. <br /> <br /> Sometimes requirements are not even coming from the business, it&#x2019;s just IT people showing off... <br /> <br /> <br />
  • Wow, that is a kind of shock for DDD zealots. Objects are there for the behavior. The domain model is an efficient way to represent behavior. If there&#x2019;s no behavior then there&#x2019;s no real need for objects as well. <br /> <br /> Did I mention that we could get rid of some of our assumptions? ;-) <br />
  • How would you optimize a Query Only architecture? <br /> - we could just use some of the tools vendor provide us to manage straight data. <br /> - we could have a specialized model for the view, with different table structure, eventually updated by a background process. <br /> - ... and many other cool ideas! <br />
  • Also, even stale data could be a great help in managing pleliminary validation of the commands. We can still perform validation on the presentation layer and make sure that most of the commands simply won&#x2019;t fail. <br />
  • Let&#x2019;s see the consequences on the command side. More trust means less burden, and a little less synchronicity, meaning less load. <br />
  • Commands are a lot closer to user intent. It&#x2019;s not just editing data. Is ding it with a purpose. <br />
  • ... so why should show entities in the presentation layer? <br />
  • The domain model turns out to become even simpler: it&#x2019;s write only. Classes are always in a consistent state and a command issued to the class, triggers an action and/or a state transition. Just that. <br />
  • Let&#x2019;s get back to the gorilla... what do we need to persist? and How? What&#x2019;s the most efficient strategy for persisting a domain model? <br />
  • Let&#x2019;s shake things a little bit more :-) <br />
  • The next little revolution is to have 2 different persistence storage: one optimized fopr working with the domain model? the other one optimized for the Query Only model. The two are eventually consistent. <br /> <br /> Just think about how many locking issues are blown away by separating the two... <br />
  • The next little revolution is to have 2 different persistence storage: one optimized fopr working with the domain model? the other one optimized for the Query Only model. The two are eventually consistent. <br /> <br /> Just think about how many locking issues are blown away by separating the two... <br />
  • The next little revolution is to have 2 different persistence storage: one optimized fopr working with the domain model? the other one optimized for the Query Only model. The two are eventually consistent. <br /> <br /> Just think about how many locking issues are blown away by separating the two... <br />
  • The next little revolution is to have 2 different persistence storage: one optimized fopr working with the domain model? the other one optimized for the Query Only model. The two are eventually consistent. <br /> <br /> Just think about how many locking issues are blown away by separating the two... <br />
  • Objects are tiny now. No collections, no mapping. Intersting things might happen... <br />
  • Surprisingly, but Udi Dahan and Greg Young in their speeches at last DDDx put the paper-based system at the center of their concern. If a complex system could work without computers ...there must be a reason for that. Some times computers just loeded the systems with more unnecessary complexity. <br />
  • Let&#x2019;s now face another assumption... <br />
  • You might also want to have a look to Alistair Cockburn exagonal architecture, you might find quite a few similarities in the problem setting. <br />
  • There might be inconsistencies in the data or between the data and the paper. In many system (especially those data-entry based) the paper used to be the Single Source of Truth, but larger integrated systems Events are probably a better candidate. <br />
  • There might be inconsistencies in the data or between the data and the paper. In many system (especially those data-entry based) the paper used to be the Single Source of Truth, but larger integrated systems Events are probably a better candidate. <br />
  • So Events are passing from the command side to the Query side in a publish-subscribe fashion, they need to ba made persistent as well <br />
  • In such a model, what&#x2019;s the best way to model an entity? Our aggregates are receiveng entities and updating state, can we achieve the same result with a more efficient strategy? <br />
  • The Specification pattern turns out really useful for that, but also note that entities are a little less mutable than they used to be. <br />
  • This might be a blast! Think about the amount of opportunities <br />
  • Ok, this one is a picture I really like, and reuse over and over... <br /> <br /> DDD has a lot to do with learning. But Event sourcing is a learning tool as well! Only, stop assuming that Business People know everything about the business, there&#x2019;s a lot more to learn for them also! Why not doing it together? <br />
  • Surprisingly, googling &#x201C;land of opportunity&#x201D; leads to Arkansas. But I like this picture... :-) <br /> <br /> <br />
  • One important lesson: you don&#x2019;t need all of this at once. But every little step brings an improvement, and it&#x2019;s worth taking. <br />
  • despite how cool this stuff looks ...be pragmatic. <br />
  • Ok, time for some useful link <br />
  • <br />
  • <br />

Transcript

  • 1. Loosely
Coupled
Complexity Unleash
the
power
of
your
Domain
 Model
using
CQRS
&
Event
Sourcing Alberto.brandolini@avanscopertas.it
  • 2. About
me In
the
IT
field
since
ZX
Spectrum Generally
in
large
scale
projects
(I
might
be
biased) Freelance
consultant:
NotOnlyCode Trainer
(Freelance
&
Skills
MaKer
+
Zenika) Technical
Writer Blogger:
h>p://ziobrando.blogspot.com TwiKer:
ziobrando
 My
e‐mail:
 alberto.brandolini@gmail.com
  • 3. @avanscoperta www.avanscoperta.it avanscoperta.wordpress.com alberto.brandolini@avanscoperta.it ©
Alberto
Brandolini
2009
  • 4. These
3
guys
 have
something
 really interesEng
to
 share
  • 5. What’s
wrong
with
that? ApplicaEon
Services Remote
facade DTO ORM UI DTO ©
Alberto
Brandolini
‐
2010
  • 6. nothing
  • 7. Thank
you alberto.brandolini@avanscoperta.it hKp://ziobrando.blogspot.com twiKer:
ziobrando
  • 8. ...What
 hump? ‐
Quale
gobba?
  • 9. How
many
assumpEons
 are
driving
our
choices?
  • 10. let’s
try
again... ApplicaEon
Services Remote
facade DTO ORM UI DTO ©
Alberto
Brandolini
‐
2010
  • 11. Anaemic Domain Model
  • 12. Anaemic Domain Model DTOs?
  • 13. Anaemic Domain Model DTOs? Optimizing ORM queries
  • 14. Anaemic Domain Model DTOs? Optimizing ORM queries Development time
  • 15. Anaemic Domain Model DTOs? Optimizing ORM queries Development time Testability
  • 16. Anaemic Domain Model DTOs? Optimizing ORM queries Development time Testability ...
  • 17. Do we really need...
  • 18. Do we really need... a Domain Model?
  • 19. Do we really need... a Domain Model? a Database?
  • 20. Do we really need... a Domain Model? a Database? transactions?
  • 21. Do we really need... a Domain Model? a Database? transactions? an Object Relational Mapper?
  • 22. Do we really need... a Domain Model? a Database? transactions? an Object Relational Mapper? DTOs?
  • 23. Anaemic
Domain
Model <<Ser vice>> <<Entity>> OrderService Order registerOrder(...) date closeOrder(...) customer checkOrder(...) amount updateAvailability(...) ... getDate() setDate(...) getCustomer() setCustomer(...) getAmount() setAmount() ...
  • 24. Not
every
present
is
 necessarily
nice
  • 25. Advantages
of
Anaemic
Domain
Model
  • 26. Advantages
of
Anaemic
Domain
Model 1)
Business
code
is
located
in
a
single
place:
  • 27. Advantages
of
Anaemic
Domain
Model 1)
Business
code
is
located
in
a
single
place: Easier
to
read
for
young
developers
not
familiar
with
 OOP
  • 28. Advantages
of
Anaemic
Domain
Model 1)
Business
code
is
located
in
a
single
place: Easier
to
read
for
young
developers
not
familiar
with
 OOP Sorry,
can’t
find
number
2
:‐(
  • 29. Disadvantages
of
Anemic
Domain
 Model Sad
as
a
hospital
meal
  • 30. Disadvantages
of
Anemic
Domain
 Model hard
to
maintain Sad
as
a
hospital
meal
  • 31. Disadvantages
of
Anemic
Domain
 Model hard
to
maintain hard
to
test Sad
as
a
hospital
meal
  • 32. Disadvantages
of
Anemic
Domain
 Model hard
to
maintain hard
to
test fosters
duplicaEon Sad
as
a
hospital
meal
  • 33. Disadvantages
of
Anemic
Domain
 Model hard
to
maintain hard
to
test fosters
duplicaEon Sad
as
a
hospital
meal
  • 34. How
to
shoot
yourself
in
the
foot avanscoper ta
  • 35. How
to
shoot
yourself
in
the
foot Design your application starting from the data model avanscoper ta
  • 36. How
to
shoot
yourself
in
the
foot Design your application starting from the data model Create your domain model by reverse engineering avanscoper ta
  • 37. How
to
shoot
yourself
in
the
foot Design your application starting from the data model Create your domain model by reverse engineering Pretend that you’re doing TDD and start testing your domain classes avanscoper ta
  • 38. How
to
shoot
yourself
in
the
foot Design your application starting from the data model Create your domain model by reverse engineering Pretend that you’re doing TDD and start testing your domain classes Particularly getters and setters avanscoper ta
  • 39. How
to
shoot
yourself
in
the
foot Design your application starting from the data model Create your domain model by reverse engineering Pretend that you’re doing TDD and start testing your domain classes Particularly getters and setters Now start testing the logic with Integration Tests and get stuck by test data related issues avanscoper ta
  • 40. How
to
shoot
yourself
in
the
foot Design your application starting from the data model Create your domain model by reverse engineering Pretend that you’re doing TDD and start testing your domain classes Particularly getters and setters Now start testing the logic with Integration Tests and get stuck by test data related issues Declare that TDD provides no benefit and only slows you down avanscoper ta
  • 41. How
to
shoot
yourself
in
the
foot Design your application starting from the data model Create your domain model by reverse engineering Pretend that you’re doing TDD and start testing your domain classes Particularly getters and setters Now start testing the logic with Integration Tests and get stuck by test data related issues Declare that TDD provides no benefit and only slows you down Comment tests in your Build-Integration process avanscoper ta
  • 42. How
to
shoot
yourself
in
the
foot Design your application starting from the data model Create your domain model by reverse engineering Pretend that you’re doing TDD and start testing your domain classes Particularly getters and setters Now start testing the logic with Integration Tests and get stuck by test data related issues Declare that TDD provides no benefit and only slows you down Comment tests in your Build-Integration process Keep on whining avanscoper ta
  • 43. I won’t reverse engineer my data model to create a domain model
  • 44. I won’t reverse engineer my data model to create a domain model I won’t reverse engineer my data model to create a domain model
  • 45. I won’t reverse engineer my data model to create a domain model I won’t reverse engineer my data model to create a domain model I won’t reverse engineer my data model to create a domain model
  • 46. I won’t reverse engineer my data model to create a domain model I won’t reverse engineer my data model to create a domain model I won’t reverse engineer my data model to create a domain model I won’t reverse engineer my data model to create a domain model
  • 47. I won’t reverse engineer my data model to create a domain model I won’t reverse engineer my data model to create a domain model I won’t reverse engineer my data model to create a domain model I won’t reverse engineer my data model to create a domain model I won’t reverse engineer my data model to create a domain model
  • 48. I won’t reverse engineer my data model to create a domain model I won’t reverse engineer my data model to create a domain model I won’t reverse engineer my data model to create a domain model I won’t reverse engineer my data model to create a domain model I won’t reverse engineer my data model to create a domain model I won’t reverse engineer my data model to create a domain model
  • 49. How
should
we
implement
a
Domain
Model?
  • 50. How
should
we
implement
a
Domain
Model?
  • 51. How
should
we
implement
a
Domain
Model? Behavior
should
be
 placed
in
the

 Domain
Model
  • 52. How
should
we
implement
a
Domain
Model? Behavior
should
be
 placed
in
the

 Domain
Model Have
your
code
 speak
the
Ubiquitous
 Language
  • 53. How
should
we
implement
a
Domain
Model? Behavior
should
be
 placed
in
the

 Domain
Model Have
your
code
 speak
the
Ubiquitous
 Language Use
Aggregates
as
unit
 of
consistency
across
 your
domain
model
  • 54. How
should
we
implement
a
Domain
Model? Behavior
should
be
 placed
in
the

 Domain
Model Have
your
code
 speak
the
Ubiquitous
 Language Use
Aggregates
as
unit
 of
consistency
across
 your
domain
model Protect
your
model
 with
clearly
defined
 Bounded
Contexts
  • 55. Anemic
Domain
Model <<Ser vice>> <<Entity>> OrderService Order registerOrder(...) date closeOrder(...) customer checkOrder(...) amount updateAvailability(...) ... getDate() setDate(...) getCustomer() setCustomer(...) getAmount() setAmount() ...
  • 56. Rich
domain
model <<Value Object>> <<Entity>> .... Order LineItem registerOrder(...) date goods closeOrder(...) customer quantity checkOrder(...) amount notes updateAvailability(...) ... calculate amount() update() ... close() ship() ... <<Value Object>> <<Value Object>> Money Customer currency name amount surname address plus(Money other) minus(Money other) annota()... ...
  • 57. s TDD
and
DDD Frequent
rewriEng Focus
on
Unit
Tests Exploratory
coding Frequent
Short
Cycles Tiny
Domain
Objects Quick
Feedback Self
explanatory
code Freedom
to
change ©
Alberto
Brandolini
‐
2010
  • 58. Aggregate ©
Alberto
Brandolini
‐
2010
  • 59. Aggregate A
group
of
objects
that
 naturally
belong
together Unit
of
consistency
in
the
 domain
model updated
in
the
same
 transacEon deleted
together transferred
together ©
Alberto
Brandolini
‐
2010
  • 60. Aggregate <<Entity>> <<Value Object>> Order LineItem date goods A
group
of
objects
that
 customer amount quantity notes naturally
belong
together ... subtotal() update() ... close() Unit
of
consistency
in
the
 ship() ... domain
model <<Value Object>> <<Value Object>> Money Customer currency updated
in
the
same
 name amount surname address plus(Money other) transacEon minus(Money other) ... deleted
together transferred
together ©
Alberto
Brandolini
‐
2010
  • 61. MulEple
aggregates Money currency amount plus(Money other) minus(Money other) ... <<Entity>> <<Root>> <<Value Object>> <<Entity>> <<Root>> Order LineItem Customer date goods name customer quantity surname amount notes address ... subtotal() ... update() ... updateDiscount() close() ... ship() ... shipping address <<Value Object>> CustomerData billing address name surname <<Value Object>> Address <<Value Object>> street city country zipcode ©
Alberto
Brandolini
‐
2010
  • 62. Isn’t
duplicaEon
bad? ‐ If
you
think
“data”
then,
...there’s
duplica6on ‐ If
you
think
“behaviour”
then
some
objects
 definitely
are
not
the
same ‐ enforcing
aggregates
boundaries
makes
your
system ‐ strictly
consistent
within
the
aggregate
boundaries ‐ eventually
consistent
outside
the
aggregate
boundaries

 ©
Alberto
Brandolini
‐
2010
  • 63. It
turns
out
to
be
simple ©
Alberto
Brandolini
‐
2010
  • 64. Why
does
it
have
to
be
hard? ©
Alberto
Brandolini
‐
2010
  • 65. Hmm... Once
coupling
 between
 aggregates
is
 dramaEcally
 reduced,
I
can
 potenEally
choose
 a
different
 persistence
 strategy
for
each
 aggregate... ©
Alberto
Brandolini
‐
2010
  • 66. From
the
same
old
stuff ApplicaEon
Services Remote
facade DTO ORM UI DTO ©
Alberto
Brandolini
‐
2010
  • 67. TradiEonal
DDD
view ApplicaEon
Services Remote
facade DTO ORM UI DTO ©
Alberto
Brandolini
‐
2010
  • 68. TradiEonal
DDD
view bou c o n n de d te x ts ApplicaEon
Services Remote
facade DTO ORM UI DTO ©
Alberto
Brandolini
‐
2010
  • 69. TradiEonal
DDD
view ApplicaEon
Services Remote
facade DTO ORM UI DTO ©
Alberto
Brandolini
‐
2010
  • 70. TradiEonal
DDD
view ag g r bou ega n d a te r ie s ApplicaEon
Services Remote
facade DTO ORM UI DTO ©
Alberto
Brandolini
‐
2010
  • 71. TradiEonal
DDD
view ApplicaEon
Services Remote
facade DTO ORM UI DTO ©
Alberto
Brandolini
‐
2010
  • 72. TradiEonal
DDD
view t hi na pp l ApplicaEon
Services Remote
facade l ay ic at io DTOe r n ORM UI DTO ©
Alberto
Brandolini
‐
2010
  • 73. TradiEonal
DDD
view ApplicaEon
Services Remote
facade DTO ORM UI DTO ©
Alberto
Brandolini
‐
2010
  • 74. Sending
Domain
Objects
to
the
UI? ©
Alberto
Brandolini
‐
2010
  • 75. Sending
Domain
Objects
to
the
UI? ‐ Nobody
really
likes
DTOs... ©
Alberto
Brandolini
‐
2010
  • 76. Sending
Domain
Objects
to
the
UI? ‐ Nobody
really
likes
DTOs... ‐ Some
tools
allow
that!
(let’s
have
some
more
 hawaiian
shirts) ©
Alberto
Brandolini
‐
2010
  • 77. Sending
Domain
Objects
to
the
UI? ‐ Nobody
really
likes
DTOs... ‐ Some
tools
allow
that!
(let’s
have
some
more
 hawaiian
shirts) ‐ Validafon
creep ©
Alberto
Brandolini
‐
2010
  • 78. Sending
Domain
Objects
to
the
UI? ‐ Nobody
really
likes
DTOs... ‐ Some
tools
allow
that!
(let’s
have
some
more
 hawaiian
shirts) ‐ Validafon
creep ‐ Double
state
objects ©
Alberto
Brandolini
‐
2010
  • 79. Sending
Domain
Objects
to
the
UI? ‐ Nobody
really
likes
DTOs... ‐ Some
tools
allow
that!
(let’s
have
some
more
 hawaiian
shirts) ‐ Validafon
creep ‐ Double
state
objects ‐ Framework
temptafon
:‐( ©
Alberto
Brandolini
‐
2010
  • 80. Sending
Domain
Objects
to
the
UI? ‐ Nobody
really
likes
DTOs... ‐ Some
tools
allow
that!
(let’s
have
some
more
 ens hawaiian
shirts) ap p at h is ‐ Validafon
creep W h I U rom t he t f ‐ Double
state
objects in er en in ‐ Framework
temptafon
:‐( d iff oma e d th l! o de m ©
Alberto
Brandolini
‐
2010
  • 81. How
would
you
implement
this? As a Sales Office I want to ship order on purchase command In order to deliver purchased goods to the customer As a Marketing Office I want to assign discount points to customer on every purchase In order to enable more deals in the future ©
Alberto
Brandolini
‐
2010
  • 82. Events
and
aggregate
coordinaEon ‐ Operafons
spanning
mulfple
 aggregates
shouldn’t
be
in
the
same
 Unit
of
Work
 ‐ Communicafon
between
aggregates
 <<Domain Event>> is
inherently
asynchronous OrderPurchased ‐ Domain
Events
as
a
communicafon
 order where mechanism when amount ‐ from
the
outside payment method ‐ among
aggregates ... ... ©
Alberto
Brandolini
‐
2010
  • 83. Domain
Event ‐ in
the
Ubiquitous
Language,
they’re
 Completed
AcEons:
verbs
in
past
tense. ©
Alberto
Brandolini
‐
2010
  • 84. Asynchronously
responding
to
events <<Domain Event>> OrderPurchased order where when amount <<Entity>> <<Root>> payment method s u bs <<Entity>> <<Root>> s to ... cri b Order su b s c ri be e s to Customer date ... name customer surname amount address ... ... onPurchaseEvent(...) onPurchaseEvent(...) update() updateDiscount() close() ... ship() ... ‐ Don’t
forget:
Business
rules
everything!!! ©
Alberto
Brandolini
‐
2010
  • 85. SOA
Anyone? ...just
draw
it
differently
 and
think
about
 “service
granularity”
  • 86. Command/Query
 Responsibility
 SegregaEon
  • 87. Why
do
we
have
to
 choose
a
trade‐off?
  • 88. StarEng
small... ‐ Command/Query
SeparaEon
was
an
OOD
 principle
part
of
DDD ‐ accessors
shouldn’t
have
side
effects ‐ mutators
shouldn’t
return
a
value
 ‐ (with
the
excepfon
of
this
in
some
cases) ©
Alberto
Brandolini
‐
2010
  • 89. Command ! Usually
targeted
to
single
enEEes Behaviour
maKers Flexibility
maKers ©
Alberto
Brandolini
‐
2010
  • 90. Query ? Large
amount
of
data No
behavior Performance
maKers Availability
of
off‐the
shelves
components ©
Alberto
Brandolini
‐
2010
  • 91. ! ? UI DTO DTO Remote
facade ApplicaEon
Services from
this... ORM
  • 92. ! ? UI DTO DTO ...to
this Remote
facade Remote
facade ApplicaEon
Services Thin
Read
Layer ORM
  • 93. ! A
separate
path
for
 commands
issued
to
the
 Domain
Model ? A
separate
path
for
querying
 Data
  • 94. ? Querying ‐ Have
a
look
to
Users,
what
are
 they
really
interested
in? ‐ It’s
not
searching,
it’s
finding ‐ It’s
not
refreshing,
it’s
 looking
for
events ©
Alberto
Brandolini
‐
2010
  • 95. ? Staleness ‐ Is
it
really
so
bad? ‐ Does
it
really
maKers
if
the
data
is...
 ‐ 20
seconds
old? ‐ Or
10
minutes? ‐ ...
who
are
we
to
decide
this? ‐ ...
can
you
keep
a
print
in
sync? ©
Alberto
Brandolini
‐
2010
  • 96. ? It’s
just
data ‐ There’s
no
behaviour
in
what
we
see. ‐ Do
we
really
need
objects
for
that? ©
Alberto
Brandolini
‐
2010
  • 97. ? Query‐Only
Architecture ‐ It’s
just
(stale)
data:
no
behaviour... ‐ =>
Why
don’t
we
go
straight
to
the
database? ‐ No
coupling
between
UI
screens... ‐ =>
Do
we
really
need
referenEal
integrity? ‐ =>
Why
don’t
we
just
a
table‐per‐UI‐view
strategy,
 calculated
in
the
background? ‐ What
are
we
already
doing
with
the
search
model
 and
the
cache? ©
Alberto
Brandolini
‐
2010
  • 98. ? Even
stale
data
can ‐ ...
provide
useful
informafon
for
 preliminary
validaEon
of
commands ‐ =>
less
failing
commands ©
Alberto
Brandolini
‐
2010
  • 99. ! ...less
failing
commands ‐ Since
most
of
our
commands
will
actually
 pass... ‐ ...
do
we
really
need
to
answer
immediately
 on
the
same
channel? ‐ What
about:
“Thank
you
for
your
order,
your
 confirmaDon
e‐mail
will
arrive
shortly”? ©
Alberto
Brandolini
‐
2010
  • 100. ! Capturing
user
intent ‐ Do
we
really
know
what
the
user
wants
to
do
with
 our
applicaEon? ‐ Are
we
really
suppor6ng
our
users? ‐ Who’s
carrying
the
complexity
burden? ‐ ...
can’t
we
do
anything
smarter
than
just
showing
 raw
data? ‐ ...most
of
the
load
olen
turns
out
to
be
simply
useless ©
Alberto
Brandolini
‐
2010
  • 101. ! Commands
!=
EnEEes ‐ There’s
not
so
much
in
common ©
Alberto
Brandolini
‐
2010
  • 102. ! Write‐only
model ‐ The
domain
model
is
not
used
to
collect
or
to
display
 data ‐ Query
oriented
relafonships
between
enffes
no
longer
 needed. ‐ The
Domain
Model
is
always
in
a
consistent
state
(from
 Factory
to
Garbage
Collecfon) ‐ No
validaEon
on
the
Domain
Model
(commands
are
 validated
before) ‐ Tesfng
the
Domain
Model
turns
even
simpler ©
Alberto
Brandolini
‐
2010
  • 103. ! PersisEng
the
model ‐ Do
we
really
need
to
persist
all
the
data? ‐ Do
we
really
need
to
persist
it
in
Relafonal
Form? ‐ (remember,
we’re
not
running
queries...) ©
Alberto
Brandolini
‐
2010
  • 104. ! ? UI DTO Commands Remote
facade Remote
facade ApplicaEon
Services Thin
Read
Layer ORM
  • 105. ! ? UI voilà DTO Commands Remote
facade Remote
facade ApplicaEon
Services Thin
Read
Layer ORM? Eventually publish
subscribe
  • 106. voilà ! ORM? ApplicaEon
Services Remote
facade Commands Eventually UI Sp e publish
subscribe cia l i ze mo d d a Remote
facade DTO ? de l ta Thin
Read
Layer
  • 107. ! ? UI voilà DTO Commands Remote
facade Remote
facade ApplicaEon
Services Thin
Read
Layer ORM? Eventually publish
subscribe
  • 108. do e voilà s it ! t o b re e re a l l y ORM? ApplicaEon
Services Remote
facade l at ne e io n d a l? Commands Eventually UI Remote
facade publish
subscribe DTO ? Thin
Read
Layer
  • 109. ! ? UI voilà DTO Commands Remote
facade Remote
facade ApplicaEon
Services Thin
Read
Layer ORM? Eventually publish
subscribe
  • 110. ! A
nice
side
effect ‐ ...
fewer
collecfons ‐ =>
less
memory
footprint ‐ =>
less
Garbage
Collecfon ‐ on
some
systems,
the
DM
is
basically
always
 available ©
Alberto
Brandolini
‐
2010
  • 111. The
paper‐based
system Many
business
pre‐date
computers TransacEons
are
ocen
NOT
a
 business
concern Data
might
be
stale...
accept
it ASK
the
Business
  • 112. Event
Sourcing
  • 113. ! So
what
is
our
DM
doing? ‐ basically
answering
to
self
contained
external
 messages... ‐ events
from
the
UI
or
from
external
sources ©
Alberto
Brandolini
‐
2010
  • 114. ! Single
source
of
truth? ©
Alberto
Brandolini
‐
2010
  • 115. ! Single
source
of
truth? ‐ Once
it
used
be
paper...
 ©
Alberto
Brandolini
‐
2010
  • 116. ! Single
source
of
truth? ‐Once
it
used
be
paper...
 ‐ now
the
best
candidate
is
Events ©
Alberto
Brandolini
‐
2010
  • 117. ! ? UI voilà Events DTO Remote
facade Remote
facade ApplicaEon
Services Thin
Read
Layer ORM
? Events publish
subscribe
  • 118. ! Do
we
need
state
in
EnEEes? ‐ We
have
all
the
needed
informafon
in
the
Event
 Queue ‐ SINGLE
SOURCE
of
TRUTH ‐ What’s
an
Aggregate?
something
that
changes
its
 state
according
to
events ‐ ...according
to
the
current
understanding
of
the
system ©
Alberto
Brandolini
‐
2010
  • 119. ! Aggregates
and
events OrderCreated MAY 3 MAY ItemsAdded Order 5 Aggregates
 date customer PriceUpdated MAY 10 track
 amount ... Events
and
 onItemsAdded(...) MAY Order Purchased onPriceUpdated(...) onOrderPurchased(...) 12 derive
 ... MAY Order Shipped state
from
 15 that OrderDelivered MAY 25 JUN PaymentReceived 26 ©
Alberto
Brandolini
‐
2010
  • 120. ! What
if
we... ‐ derive
the
Aggregate
state
from
the
sequence
of
 events
that
occurred
in
the
system? ‐ =>
We
can
add
retroacEve
features... ‐ =>
We
can
say
YES
to
a
lot
of
interesfng/awkward
 request
for
the
business. ‐ =>
Reproducing
bugs? ©
Alberto
Brandolini
‐
2010
  • 121. ! ©
Alberto
Brandolini
‐
2010
  • 122. The
land
of
opportunity Loosely
coupled
 aggregates
allow
 be>er
 simpler
 scalability development Polyglot
 persistence Painless
 Rewindable
 SOA applicaEons
  • 123. Start
small you
might
not
need
all
of
it each
step
is
an
 improvement Even
in
Eny
architectures ...challenge
one
 assumpEon
at
a
Eme
  • 124. References
 h>p://groups.google.com/group/dddcqrs h>p://cqrs.wordpress.com/ h>p://www.infoq.com/interviews/Architecture‐Eric‐Evans‐Interviews‐Greg‐Young h>p://www.udidahan.com/2009/12/09/clarified‐cqrs/ h>p://www.infoq.com/presentaEons/Command‐Query‐Responsibility‐SegregaEon h>p://www.infoq.com/presentaEons/SOA‐Business‐Autonomous‐Components h>p://marEnfowler.com/eaaDev/EventSourcing.html h>p://skillsma>er.com/podcast/design‐architecture/architectural‐innovaEon‐evenEng‐ event‐sourcing ©
Alberto
Brandolini
‐
2010
  • 125. Thank
you alberto.brandolini@avanscoperta.it hKp://ziobrando.blogspot.com twiKer:
ziobrando