en-mood

In my article "From AmigaBASIC to AI", I talk about my early days in programming: from my early influence by BASIC to the wild times with the Amiga, the demo scene, and ARexx. This path eventually led me to study computer science and become a professional software developer using OOP, PHP, and PHPUnit.

However, as I described in "Testing with(out) dependencies", understanding the syntax was only the first step. The real challenge was to understand the meaning behind the objects. The distinction between identity-based entities, interchangeable value objects, and stateless services was a fundamental "aha moment" for me. It was the point at which mere code became a model of reality.

But as is so often the case in software development, one answer only opens the door to new questions. After learning how we structure code (entities, values, services), I faced the next big hurdle: How do we model time and change?

The next step

The realisation that not all objects are the same was my introduction to Domain-Driven Design (DDD). While my early attempts at OOP focused heavily on the state of objects or the data in the database, DDD taught me to focus on behaviour.

This is where the concept of Command/Query Responsibility Segregation (CQRS) came into play. CQRS taught me to strictly separate read and write logic and not to mix them in the same classes. The Single Responsibility Principle, the "S" in "SOLID", comes to mind.

  • Commands change the state of the system (write)
  • Queries ask about the state (read)

This separation felt similar to the liberation I had felt when I made the transition from procedural code to true object-oriented programming. Suddenly, my services became leaner and more focused.

The truth lies in the events

However, the most radical change in my thinking came with Event Sourcing. In "Testing with(out) dependencies", I described entities as objects with an identity that remains constant over time. Traditionally, however, we only store the current state of this entity in relational databases. Everything that happened before is overwritten and thus forgotten. Such a system is also known as a CRUD system, where the individual letters of the abbreviation stand for the operations Create, Read, Update, and Delete.

Event Sourcing reverses this principle: Instead of only storing the "now", we store the history, i.e. the sequence of events that led to this state.

This approach turned the vague state changes that I used to hide in my entities into explicit facts from the domain: "bank account opened", "money deposited", "money withdrawn", and so on.

From code to communication

All these technical patterns – DDD, CQRS, Event Sourcing – are powerful, but they do not solve the biggest problem in software development: the misunderstanding between the business side and development.

This is where the Event Storming methodology, which originates from collaborative modelling, comes into play. It is based on collaboration and the mutual exchange of knowledge among all participants. Everyone contributes their own perspectives, skills, and experiences, resulting in a common understanding of the problem. This shared understanding forms the basis for developing solutions. The goal is to achieve better results through intensive collaboration.

Instead of drawing UML diagrams alone in a quiet room (or, as in my studies, programming on paper), event storming brings all participants into one room. Using countless orange sticky notes, we jointly model the timeline of the domain based on events. It is fascinating to see how this method bridges the gap between the services and entities in the code and the real business processes.

Event Storming
Stefan Priebsch leads an event storming workshop: participants collaborate on a large-scale visualisation and arrange yellow sticky notes to model business processes.

I experience how valuable this exchange is every year at ComoCamp in Vienna. Events like this show that methods such as Event Storming are not theoretical constructs, but living tools that are developed collaboratively.

Conclusion

My journey began with print "Hello world" in AmigaBASIC and led me to discover objects and gain a deep understanding of domains and events. Looking back on my beginnings today, I see a clear line: we are constantly trying to find better abstractions to translate the complexity of the world into software.

The realisation that not all objects are the same was important. But the step from "we only store the current state" to "we keep a record of all events" was revolutionary.

Understanding these concepts is one thing. Putting them into practice, especially when it comes to testing, is another. In my next article, I explore how these patterns of DDD, CQRS, and Event Sourcing come together in a concrete way: how we can align our tests with the language of Event Storming, transform testing from a burden into a bridge, and generate living documentation directly from our test suite. The theory becomes practice, and the circle from requirements to code to documentation closes.