Chapter 5 - Event Sourced aggregates are hard to refactor

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 of the fourth villain of our story.

Aggregates, especially event-sourced ones, are hard to refactor!

Designing the right aggregates is difficult; it is easy to make modeling errors.
Furthermore, the requirements change over time, and the aggregates could need to be modified accordingly. Whatever the reason, solving a late-stage mismodeling problem can be very expensive.

In particular, by adopting event sourcing, we create a bond between the domain event and its aggregate.
Each domain event is part of one and only one aggregate.

Refactoring an aggregate may require a partial or full re-write of the event store. Many times, this is not so simple. It also happens that, to avoid facing a rewrite of the event store, one prefers to abandon the refactoring, accepting to live with the wrong choice initially made.

The story continues to the next chapter
Chapter 6 - The aggregate could cause unnecessary complexity

... or watch the full story on youtube


  1. I would argue that refactoring a non-event-sourced aggregate is even harder. Besides the code, there is usually a complex db schema migration required. It's hard to run the migration slowly and very often the stop-the-world point is mandatory to make the migration correct. Whereas with event sourcing an aggregate is just a projection from events. It is a very specific one because it is used for keeping the state correct, but still, just a projection. When working with event sourcing I feel more comfortable with the aggregate design because I can always replay events and create a different aggregate. Splitting the aggregate is a bit more sophisticated but, in general, easier than without event sourcing. Also, I can run the migration in parallel to the normal processing and do the quick switch when I'm ready.


Post a Comment

Popular posts from this blog

Chapter 1 - I am here to kill the aggregate

Chapter 2 - The Aggregate does not fit the storytelling

Chapter 8 - The death of the aggregate