DDD - Modelling the Domain - Entities

Entities are objects of the domain model with a distinct identity and a life cycle (Evans, 2003). Moreover, the key defining characteristic is not the values of their properties which could change over time (Evans, 2003). The uniqueness of an Entity's identity is defined by the model and does not change during its lifetime (Evans, 2003).

For example, consider modelling the concept of a Person with a first/last name, a birth date and genre. Obviously, using the combination of the first and last name as the unique identity is problematic. If the Person is a woman which got married, the last name could change leading to data corruption.

Entities are not mere data structures and emphasis is given to their methods providing rich behaviour (Evans, 2003). As an example, consider modelling a SecureDoor as an entity with a unique identity that can be opened, closed, locked an unlocked. In order to unlock the door we need a Key (i.e. a Value Object):

key, lock = lock_factory.create(pin=123456)
door = SecureDoor(identity=321, secured_by=lock)
door.lock(key)

As shown above, a Key and a Lock are created by a LockFactory, then a SecureDoor is created protected by a specific Lock instance and finally we lock the door using the lock's key. The Key does not know how to unlock the door or the locking mechanism hidden inside the door. If the key does not fit within the locking mechanism the door will refuse to change its state from locked to unlocked.

The identity of entities should be unique and Vernon (2013) suggests four different ways to introduce it:

  • The user of the application: when a user creates an entity he/she is asked for a unique identifier. For example, a user creates a Project titled “my first project for customer X” and chooses the string “PRJ1-X” as the unique identifier.

  • The application itself: a Universally Unique Identifier (UUID) is generated and associated with the instance of a new Entity.
  • The persistence mechanism: this is the most common case where an identity is created only after the entity is persisted. The database maintains a sequence for each table and each time a new row is added, the sequence is increased and a new integer ID is generated.
  • Third party system: the application relies to a third-party remote system to provide and guarantee a unique identity. For example, an online shopping system has to register a new user but needs to send a remote request to the customer relationship management (CRM) system to retrieve the identity.

References

  • (Evans2003) Evans, E. (2003) Domain-Driven Design: Tacking Complexity In the Heart of Software. Boston: Addison-Wesley.
  • (Vernon2013) Vernon, V. (2013) Implementing Domain-Driven Design. Boston: Addison-Wesley.

This post is an excerpt of my MSc Thesis titled "Applying Domain-Driven Design in Python - designing a self-hosted Read-it-Later service" (January 2014).

This article was updated on

Related post

DDD - Modelling the Domain - Value Objects

There are elements of the Domain Model without any conceptual identity which are typically used to characterise Entities (Evans, 2003). Those elements are called Value Objects and their significance is often neglected (Vernon, 2013). Examples of Value Objects are: Zip Code, Order Number, Phone Number, Money, Currency, Date, Date Range, E-mail Address, URL etc. Value Objects express domain concepts and are part of the Ubiquitous Language (Evans 2003; Vernon, 2013).

Domain Driven Design

Domain-Driven Design (DDD) is an approach to drive complex software projects using a set of principles, software design practices and techniques by directly aligning the code with the concepts in the domain (Evans2003). The concept was established by Eric Evans in his book “Domain-Driven Design, tackling complexity in the heart of software”. Vaughn Vernon notes that Evans' book “is essentially a large pattern language” (Vernon2013).