Entities and Value Objects in Domain Driven Design
Published on Feb 02, 2024 14:47 by KE Programmer
Table of Contents
1. Introduction
Two common concepts that one will encounter in Domain Driven Design are entities and value objects.
2. Examples
A person could be represented as an entity, whereas their name is a value object.
In a financial transaction, the transaction is represented as an entity and is stored in perpetuity, whereas the amount involved is a value object composed of an number and a currency unit.
3. Explanation
An entity is a long lived object in the domain that has an identity, whereas a value object is a characteristic of an entity without an identity of its own. A value object is its data. Two value objects with the same data are the same thing.
Let us consider a person named Jack Ma . Jack Ma will always remain a unique individual throughout their lifetime. If he changes his first name to John, his identity doesn't change even though his name did.
Two different people may be named Jack Ma, and as value objects, their names are equal. However the people who have these names are considered different entities.
4. Sample Code
In Python we can represent value objects using immutable objects like named tuples or frozen dataclasses.
>>> from collections import namedtuple >>> Name = namedtuple('Name', 'first_name', 'last_name') >>> Name('John', 'Ma') == Name('Jack', 'Ma') False >>> Name('John', 'Ma') == Name('John', 'Ma') True
Entities can be represented as mutable objects that are composed of value objects. Even if two different entities may have similar characteristics, each is unique.
>>> class Person: ... def __init__(self, name): ... self.name = name ... >>> person1 = Person(Name('Jack', 'Ma')) >>> person2 = Person(Name('Jack', 'Ma')) >>> person1.name == person2.name True >>> person1 == person2 False
Entities can be assigned a unique id that is then be stored in the
database, so that it is persistent across restarts or in distributed
applications. The dunder method __eq__ can be overridden to help
with equality operations on these entities.
class Transaction: def __init__(self, uid): self.uid = uid def __eq__(self, other): if not isinstance(other, Transaction): return False return self.uid == other.uid >>> t1 = Transaction(1) >>> t2 = Transaction(2) >>> t1_other = Transaction(1) >>> t1 == t2 False >>> t1 == t1_other True
