Search code examples
domain-driven-designaggregateroot

Entity in Aggregate Without Identity?


I've been trying to wrap my head around domain-driven design concepts and a question I keep coming back to is how to deal with functionality that I would normally implement using a mutable class but doesn't have an identity of its own in the domain.

Example Domain

Let's say we have a Game Board entity that is responsible for updating the positions of various tokens in a simple board game (like chess). Let's also assume that players are scored on how long they have been playing the game not including any time during which the game was paused. The logic for updating an elapsed time and updating a game board are fairly different so we create a Timer class to encapsulate the functionality of storing and calculating game time. Finally, we want to disallow updates to the Game Board while the game is paused and want to ensure the Timer is paused/resumed when the game is paused/resumed so we create a Game aggregate with a Game entity that enforces these invariants by providing its own pause/resume/move methods that wrap the calls to the methods of the underlying Timer and Game Board (and disallows external access to the methods of these objects that mutate their state).

The Problem

Both Timer and Game Board are mutable in this example and have complex business logic that drives their state changes so it feels wrong to just combine their logic with Game's; furthermore, a Game will only ever have one Timer and one Game Board that exclusively belong to that specific instance so it doesn't seem as if these two objects really have identities of their own. It also doesn't make sense for either of these objects to exist outside their Game.

Question

Is it fair to say that Timer and Game Board are just entities that implicitly have the same identity as the Game holding them (to signifiy that only one instance of each can exist per Game)? If so, do these classes representing these entities actually need to hold references to their aggregate's Game Id (assuming that is Game's identity) or can their existence in the aggregate be all that is needed to associate them with it?

If not, is there something I'm missing that resolves this issue without just combining all three concepts into one?


Solution

  • There are two reasons (regarding your design) why an Entity needs an Id.

    1. The game object needs to distinguish many instances of the same entity type without comparing its content.
    2. Your ORM or database system requires you, to have an Id in every data object you persist.

    If you don't need any of the two above (and you don't need point 1), there is no need for Entity to have an Id.

    If you are asking, how this concept looks like from a DDD perspective, my thoughts look like this: Domain-driven design, on the implementation level, doesn't care about Entities, they are not even a part of the ubiquitous language in many cases. They are just a concept that helps to break down a big AR into smaller, more cohesive parts.

    I've made a lot of systems, that had even aggregate roots with the same Id with a type Suffix. In a Relational database, you can create a foreign key on two primary keys, effectively creating one to one relationship between tables, which is perfectly valid from my point of view.