EventStorming at Aardling

Insight

  • Domain modelling
  • Software Decision-Making

How we teach EventStorming at our clients

EventStorming at Aardling

EventStorming is a very popular modelling technique that was first introduced by Alberto Brandolini. At Aardling we use a somewhat different approach than the “Brandolini” style of EventStorming. Let me show you our style and why we prefer to use it.

This blog is not a tutorial, but rather a quick explanation of how we practice EventStorming. Watch our modelling video series for a more in-depth look at how we model.

These are the basic building blocks we use in EventStorming:

A stack of events, from left to right: commands in blue, constraints in pink and events in orange

💡 Tip: Whiteboard tools, like Miro or Lucid, allow you to use a stack of sticky notes, making it easier for participants to add new ones.

Domain Events

👉 a domain event: something that’s relevant to the domain, expressed in the past tense. Examples are "Invoice Was Paid", "Subscription Renewed". Events represent facts, things that have happened.

When we start modelling we often start by just using events to represent the problem space and use cases. Once we are in a workshop with domain experts, we visualise the events to tell a coherent story. This process starts with uncertainty and chaos and evolves until we have built a rich, shared understanding of the problem space. That is to say, we are not making decisions about a solution yet, we’re still focused on the problems.

Once we’re happy with what we’ve learned and want to explore it further, we add commands and constraints.

Adding commands and constraints

👉 Commands, sometimes referred to as actions, express an intent to do something. Expressed in the imperative. A user or a system wants to do something. Examples: “Pay invoice”, “Renew Subscription”.

👉 Constraints express a decision, condition, or anything that influences the outcome of a command or an event.

To start with, our EventStorm will look something like this. Orange stickies represent the events.

a whiteboard with a bunch of orange stickies representing the problem space

Now let's introduce the following pattern:

command → constraint → event pattern

First, we capture the action (command) someone, or something, wants to trigger. But in order to proceed, we need to consider the business constraints. If they pass, a decision is made (event).

For example, reserve table → table must be available → table reserved

visualisation of the example: reserve table → table must be available → table reserved

Of course, there might be multiple constraints which we will represent like this:

command (reserve table) → 3 constraints in series (table must be available, reservation time between 7pm-10pm and table size fits all guests)  → event (table reserved) pattern

Or like this if we don’t care about the order of the constraints:

command (reserve table) → 3 constraints in parallel (table must be available, reservation time between 7pm-10pm and table size fits all guests) → event (table reserved) pattern

When we think that there are no constraints between the trigger and the outcome, we make that explicit by introducing the Always constraint. This step documents that a conversation was had and no constraints were found.

command → always → event

Often we have conversations that go something like this:

Always, when this happens, then that happens …”

”Is that really always what happens?”

“Yes”

”Oh, and what about when this happens, then that happens…?” ”

Ah, you’re correct, in that case, it should actually fail”

We have found that removing the always constraint often removes the conversation altogether, which results in missing constraints.

One final pattern that I’d like to add is:

  • event → constraint → event or

  • event → constraint → command

The definition of a constraint says it is anything that influences the outcome of a trigger. A trigger can be an event as well, so you could have examples like the one below:

subscription renewed → customer with post payment → payment requested
payment succeeded → business customer → prepare invoice

Often we need to know what happens if the constraint fails. In that case we model both paths:

command -> constraint -> happy or failure path -> domain event

This is a very high-level overview of our EventStorming process, but it includes the fundamental building blocks you will need to start. Try it out in your next session and see how it goes. The best way to improve your EventStorming skills is to do it and to incorporate what you learned into your next session.

One final tip would be to add your own visual language to express things that are important in your context, for example, maybe you want to use different colours for different systems emitting the event, or for a different colour for summary events.

Don’t overthink it, but go for it.

If you have questions or feedback, find me on Linkedin/BlueSky or you can write to us.