The other day a friend asked me what is the difference between a Value Object and a Domain Model, and when I would suggest using one over the other?
Since I have been asked this very same question quite a few times, I thought it might prove useful to provide a brief definition in the context of a language agnostic idiom which could serve as a point of reference for others as well. Thus, below is general definition of each.
A Domain Model is anything of significance which represents a specific business concept within a problem domain. Domain Models are simply classes which represent such concepts by defining all of the state, behavior, constraints and relationships to other Domain Models needed to do so. Essentially, a Domain Model “models” a domain concept, such as a Product, a User, or anything which could be defined within a problem domain itself, outside of the context of code.
Domain Models promote reuse and eliminate redundancy by defining specific classes which encapsulate business logic, state, behaviors and relationships. As business domain concepts change, so to do the implementations of the Domain Models.
As the name implies, a Value Object, more commonly referred to as a VO, is an object which simply provides values, nothing more.
Value Objects are entirely immutable; that is, all properties are read-only and assignments to those properties are specified only during object creation; after which, properties can not be modified and, by design, should not require changes.
Value Objects are typically used to provide an aggregation of conceptually related properties whose values describe the initial state of the object when instantiated and do not require any real concept of identity or uniqueness. While there are some edge cases (such as validation), more commonly than not, Value Objects do not implement any specific behavior. Conceptually, think of a Value Objects as being nothing more than an object which holds a value, or series of related values, which describe something about the object when created.
It is important to make the distinction between Value Objects and Domain Models, as a Value Objects is not a Model, but rather, it is nothing more than an object which holds values and could be used to describe any particular context. Perhaps a good example of a Value Object could be a JSON object returned from the server. That is a Value Object. A Domain Model could then wrap the Value Object in order to provide state changes, validation and behaviors.
And that’s it
Hopefully the above descriptions of both Domain Models and Value Objects will clear up any confusion surrounding the two concepts; ideally, making it easier to understand when to use each.
The point to keep in mind is that Domain Models simply model a business concept, including it’s rules, constraints and behaviors, while Value Objects simply describe a contextual state.