Domain-Driven Design

Value Objects in Domain-Driven Design

Objects defined by their attributes rather than identity — and why immutability makes them safe to share.

January 20, 2026
#ddd#value-objects#design-patterns

A Value Object has no conceptual identity; it is defined entirely by its attributes. Two Money objects representing €10 are interchangeable regardless of which instance they are. Value objects should be immutable: operations return new instances rather than mutating state. This makes them safe to share across the model without defensive copying.

php
final class Money
{
    public function __construct(
        private readonly int $amount,    // in cents
        private readonly string $currency,
    ) {}

    public function add(Money $other): self
    {
        if ($this->currency !== $other->currency) {
            throw new \DomainException('Currency mismatch');
        }
        return new self($this->amount + $other->amount, $this->currency);
    }
}
Immutable Money value object

Continue reading