Avoid primitive obsession with EventSourcing

I am creating a small game as a training exercise to create an application using Event Sourcing as a save mechanism.

One problem that I am currently facing is a very primitive obsession in my application.

Player is a central concept, player names must be unique, so I used PlayerName as an identifier for events in my game. This is a string.

Until that moment, I left with event handlers that could store a list of player names (in the form of strings) to represent the players in the game and their various states. However, the last important role that I added to the game required me to make changes in several places (and not just one). I left it a bit before introducing some "real" objects.

The problem I am facing right now is that every event handler that deals with an event related to a player (or several players) requires a kind of search to find and find the Player object matching the value of PlayerName .

It seems that there will be a lot of duplication in the handlers now, since they need to go and "Get" different players from the search (until this moment I had no getters / setters on my domain objects, I think it's worth spending money to remove a primitive obsession but I would like the solution not to require from me).

It seems to me that I missed a piece of the puzzle, but I'm struggling to put it on.

+4
source share
2 answers

Do your aggregators have access to the player name when creating events? If a player’s name is important to event handlers, it should probably be part of the event payload.

Adding additional information to events that can be used downstream is called event enrichment . I do not know the structure of your events, but they often contain much more data than the original command. And this additional data can be saved as primitives.

A primitive obsession can be an odor within a domain model. I do not consider this a problem when it comes to events. I would even say it the other way around. You want your events to be independent of other classes in order to maintain a connection between contexts, and they can be easily used in an integration script.

+1
source

If you can control enough how events are generated, you can replace PlayerName with some kind of provider object:

 class PlayerProvider { PlayerCollection _players; // where you ultimatively look up players from string _playerName; public Player Player { get { return _players[_playerName]; } // looks up the player on demand } } 

Then, when events are generated, insert them with the correspondingly initialized PlayerProvider .

0
source

Source: https://habr.com/ru/post/1436981/


All Articles