Worked example — value object and entity, side by side in Python.
Python's dataclasses module gives us almost everything we need. The single keyword that flips a class into a true value object is frozen=True:
from dataclasses import dataclass, field
from decimal import Decimal
from uuid import UUID, uuid4
# Value object — immutable, compared by value.
@dataclass(frozen=True)
class Money:
amount: Decimal
currency: str
# Entity — identity persists across changes, compared by id.
@dataclass
class Customer:
id: UUID = field(default_factory=uuid4)
name: str = ""
def __eq__(self, other: object) -> bool:
return isinstance(other, Customer) and self.id == other.id
def __hash__(self) -> int:
return hash(self.id)
Why each line is there:
@dataclass(frozen=True) makes Money immutable — Money(10, 'EUR').amount = 20 raises.
frozen=True also makes Money hashable and gives free value-equality: Money(10, 'EUR') == Money(10, 'EUR') is True.
Customer is left mutable but adds an id field with a UUID default.
- The explicit
__eq__/__hash__ make two Customer instances with the same id equal even if their name differs — that's identity-based equality.
Use this snippet as your template for the playground below.