In this chapter, you got to use the feature of representing state transitions inside aggregates as events. I used that code style from the start intentionally, although I can imagine that it may have caused you some confusion. At the end of the day, why would you need to split each operation into Apply and When? Using that approach was necessary to prepare the readers for this chapter. Using domain events is a good practice, overall. Even if you don't use Event Sourcing, you should definitely consider using domain events to communicate updates between aggregates, and even between different Bounded Contexts, and using domain events for state transition makes it easy, because you will always have a list of changes as a collection of new events.
Since we had this collection ready, we only needed to figure out how to store those changes as-is, in an event stream that...