Value Object
A value object is an object defined entirely by its attributes: two instances with the same values are interchangeable, so it carries no identity and no lifecycle. Money, a date range, a coordinate. Make it immutable and value equality follows naturally; you replace a value object, you never mutate it.
Read through intent and mechanism, this is the audit‘s one pattern whose mechanism improved after 2003. The intent predates Evans (Ward Cunningham’s Whole Value, credited in the Blue Book’s own footnotes; Fowler’s 2002 catalog named the pattern months before the book), and the 2003 mechanism, hand-written equality plus immutability by discipline, became a compiler guarantee: records in Java and C#, data classes in Kotlin, structural equality for free in F#. Evans allowed a performance-driven exception to immutability in 2003 (a force that has since expired); the 2015 Reference states the immutability guidance without that caveat.
The field’s default tilts this way too. Vernon says to strive for value objects instead of entities wherever possible, Khononov says whenever you can. When in doubt, model the thing as a value first and promote it to an entity only when the domain genuinely tracks it through change.
data class Money(val minorUnits: Long, val currency: Currency)
Signal: swapping two instances with the same attributes changes nothing the domain can observe. Part of Domain-Driven Design.
Sources
- Ward Cunningham, The CHECKS Pattern Language (1994): Whole Value, the value object’s ancestor, credited in the Blue Book’s own footnotes.
- Martin Fowler, Value Object (2002): named the pattern months before the Blue Book.
- Eric Evans, Domain-Driven Design Reference (2015): states the value object’s immutability without the 2003 performance caveat.
- Vaughn Vernon, Implementing Domain-Driven Design (2013): strive for value objects instead of entities wherever possible, echoed by Vlad Khononov, Learning Domain-Driven Design (2021).