Common line-of-business applications typically are built using the MVC design pattern with the database tables representing the model tier in MVC as the single source of truth for the application state.
Event-based systems are different – and inherently more complex – in that their single source of truth is the stream of events that led to the current application state. For example, instead of updating a model object (and its underlying database table) a system using event sourcing would simply emit an ‘object value changed to x‘ event. By replaying all events in sequence an application based on event sourcing can determine the current state of an object. In other words, when queried about a specific entity the application reduces all relevant events to the current state of that entity. If you’ve ever used Redux this might sound familiar because that’s exactly the pattern Redux uses with its actions and reducers.
Event sourcing in turn draws upon the CQRS pattern because with that kind of design the model responsible for viewing data is different from the model responsible for modifying data. Again, this adds complexity to a system. However, in many cases that’s worth the trade-off. Often, perhaps due to a misunderstanding of domain-driven design concepts, every possible aspect of a business’ domain gets shoehorned into a single authoritative model.
Nominally, these models represent everything that can happen in a business. Practically however, commonly they’re so conceptually complex that they don’t fit any use case well or at least not as well as they could had they been designed with bounded contexts in mind. In all but the most simple businesses it therefore absolutely makes sense to have a different model for each bounded context, for each aspect of that business (sales, marketing, production etc.). This both avoids misunderstanding between different business functions about what a software does (or is supposed to do) and significantly reduces the complexity of the models involved.
Apart from functional requirements such as being able to
- rebuild application state
- replay events for debugging purposes
- temporally querying application state (e.g. “What did this entity look like 2 hours ago?”)
event sourcing and CQRS also lend themselves to being used as a tool for domain-driven design in complex businesses with many business functions (sales, support etc.). Event sourcing allows each function to work with the model best suited to its work while the result of that work can be reconciled by using the system’s event log as a single source of truth.
This and a variety of other aspects of event sourcing are further explained in these 2 articles: