Posts

Showing posts from April, 2023

Chapter 10 - The Aggregate is dead

Image
continues from  Chapter 9 - An event is just a fact, pure ...... The aggregate is finally dead, together with its negative aspects. This new approach, which focuses on the decision block, has several benefits: Perfect match with storytelling Focus on behavior instead of model Less contention Less complexity  Simpler to refactor But be careful: this does not mean having to organize the system in order to have hundreds of completely unrelated command handlers. Absolutely not! Clustering commands into logical groups and delegating their execution to the same model is and remains a correct programming approach. The difference lies in the fact that before, by the very definition of aggregate, these models necessarily had to be isolated from each other. Killing the aggregate means admitting the possibility of contamination between these models without renouncing consistency. A less dogmatic approach, which in any case must not disregard good programming practices, but which, thanks to greate

Chapter 9 - An Event is just a fact, pure

Image
continues from  Chapter 8 - The Death of the Aggregate ....... Surely you remember that, in modeling the Student aggregate and the Course aggregate, we defined some events that looked like duplicates: They were necessary to validate the respective invariants of the course and the student during the subscription process. If we had a weird feeling during the event storming phase, the feeling doesn't improve later. Indeed, reading the content of the event store, we can notice that for each subscription, there are two close events with the exact same content! They differ only because they originate from one or another aggregate (represented here by the colors red and green). How can we get rid of this? In reality, the domain event is only one: its duplication is functional to the existence of the two aggregates.  But if we get rid of the aggregate, then as a direct consequence, we might also get rid of the duplication of these events. Indeed, if we get rid of the aggregate, then an eve

Chapter 8 - The death of the aggregate

Image
continues from  Chapter 7 - Focus on the behavior ...... Event sourcing provides a huge advantage, because it decouples the persistence from the model needed for making a decision. Any message handler can build, on the fly , any model needed for making a decision, starting from the correct event stream. Let's make a practical example to understand better. Assume we need to handle the UpdateCourseCapacity Command .  This is a representation of the Event Store, where the events belonging to the course aggregate are highlighted in green. If we decide to use the classic aggregate approach, we need to reconstruct the Course aggregate starting from the stream of its events. Let's take a different approach instead, where the command handler is responsible for retrieving the model needed to make a choice. We immediately realize that not all the events that are part of the Course Aggregate contain information useful for our purpose. For example, the fact that the course has been rename

Chapter 7 - Focus on the behavior

Image
continues from  Chapter 6 - The aggregate could cause unnecessary complexity ...... Can we happily live without aggregates? I think we can! Since it is difficult to design the right aggregates, I asked myself: can we guarantee consistency in another way? In a more flexible and less constraining way than the aggregate one? The secret, from my point of view, is to focus on the behavior, not on the model. We want to go back to the fluidity, the naturalness, and the beauty of storytelling. Imagine simplifying the system as much as possible, until it is nothing more than a series of actions and reactions. The causal link between them is represented by a decision, taken on the basis of one or more business rules. This is precisely the atomic element we need, the block that connects a specific trigger to its consequences . We could compare this chain of actions and reactions to a game of ping pong between a person and the system. On one side, the person, triggered by a certain situation,  is

Chapter 6 - The aggregate could cause unnecessary complexity

Image
continues from  Chapter 5 - Event sourced aggregates are hard to refactor ...... Let's add a little more spice to our example, introducing rule number 4: A course cannot accept more than N students N, the Course Capacity, can change at 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) The course title can change at any time to any title different from the current one The student cannot join more than 10 courses Back to the board! We need a new event for the creation of the student, and the relative command. But here, things get complicated, since we need a new event for the subscription and a new event for the unsubscription. Both triggered by their respective commands. Déjà-vu? Yes, because we have already met very similar events and commands when we were talking about the course.  But now we need two more pairs, because the newly introduced rule is relative to a new aggregate: the stu

Chapter 5 - Event Sourced aggregates are hard to refactor

Image
continues from  Chapter 4 - The larger the Aggregate, the greater the contention ...... What if we realize only in an advanced stage of development that we have modeled the aggregate incorrectly? Of course, it depends! If we are using State Persisted Aggregates, we could transform the aggregates with some scripts. If we are using Event Sourced Aggregates, the situation gets complicated. This is the representation of an event store; the highlighted events belong to a specific instance of the Course aggregate.  If we decide to refactor this aggregate, replacing it with the CourseSubscription and CourseInfo aggregates, we need to rewrite the event store. The course creation event is replaced by two events for the creation of the two new aggregates: CourseSubscription and CourseInfo. The other events belonging to the Course aggregate are replaced by events belonging to the CourseInfo or the CourseSubscription aggregates. The color represents the new aggregate instance. Here we are in front

Chapter 4 - The larger the Aggregate, the greater the contention

Image
continues from  Chapter 3 - The aggregate mixes technical and business aspects ...... Let's add something new to our example, introducing rule number 3: A course cannot accept more than N students N, the Course Capacity, can change at 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) The course title can change at any time to any title different from the current one We need to introduce a new event, to represent the fact that the course has been renamed. And a new command to request the change of the Course's title. Who should this command be sent to? The most common answer is: " to the Course ". The Course aggregate is now responsible for something more than before. It may seem irrelevant, but it hides a pitfall. Let me introduce you to the third villain in our story: The larger the Aggregate, the greater the contention! The natural attitude to choose as aggregates the bu

Chapter 3 - The aggregate mixes technical and business aspects

Image
continues from  Chapter 2 - The Aggregate does not fit the story telling ...... Let me introduce villain number 2. The aggregate mixes technical and business aspects. For some reason, consciously or not, we try to bring together, in the aggregate, two different models: the model to guarantee the invariants our mental model of the domain concept Although this may seem natural, often, these two models do not coincide. Strong consistency constraints do not always reside within the same business concept. It may happen that there are consistency constraints in the intermediate area between two or more business concepts. For some people, this difference between the domain concept and the consistency boundary is crystal clear. I was positively impressed by the technique used by my friend Mauro Servienti to model the aggregates. He takes a reverse approach, first grouping data that share consistency constraints, bringing together information that changes together or whose change is dependent.

Chapter 2 - The Aggregate does not fit the storytelling

Image
continues from   Chapter 1 - I am here to kill the aggregate ...... One of the most powerful elements of DDD is that it has broken down the barriers between technicians and domain experts, thanks to tools capable of exploiting the immense potential of storytelling, first of all Event Storming. Storytelling is at the heart of human communication. Storytelling does not require any special competence or skill. It helps break down the barriers between technicians and business experts. In my experience, the usage of storytelling ensures an exceptional fluidity in the domain discovery process, but it hits a snag when we try to introduce the aggregate into the story. Indeed, by definition, the aggregate is the boundary of consistency. The aggregate is the component responsible for ensuring strong consistency constraints within an ecosystem that is, by nature, eventually consistent. But, at the same time, it tries to represent the business entity acting as the guardian of a set of business rul

Chapter 1 - I am here to kill the aggregate

Image
The aggregate has always been, for me, one of the most controversial and weakest elements of Domain Driven Design. During my consultancy activity, I have been able to verify that the full understanding of the aggregate concept remains difficult for many. It is easy to make mistakes in the modeling phase, which will be very complex to fix in more advanced stages of development. As a result, some developers feel that the whole architecture is excessively difficult and complicated. I want to show you another world, where there is no aggregate. I am here to kill the aggregate. For those unfamiliar with it, let me introduce it to you. The Aggregate Its definition is, in my opinion, is quite vague: 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 If you are confused by this definition, let's try to read what the blue book recommends for