Stop Primitive Obsession With Value Objects
Value objects are objects with domain meaning but no conceptual identity.
Primitive Obsession
I realised I was falling too much into primitive obsession because I was missing something in my developer toolkit.
That tool was the concept of Value Object.
Example: E-commerce
We’re developing an e-commerce site. We start with the product entity.
Product {
id: string;
name: string;
description: string;
// PRIMITIVE OBSESSION
price: number;
}
We set the “price” attribute to a number. It works now because we only sell in euros and each product has just one price.
Expand to Other Countries
Our site has expanded to other countries, and now we need to support currencies. We could add another property:
Product {
//…
price: number;
// MORE PRIMITIVE OBSESSION
currency: string;
}
This is ugly, and it creates other problems that need to be solved:
What if the same product is sold in different countries?
How do we compare prices when they have different currencies?
How do we change prices for offers in specific periods?
The wrong model has just created a bunch of problems that wouldn’t exist with a more accurate data representation.
Price Is a Concept
The price is a concept in itself. Similar to the product, which is also a concept. Therefore, the price deserves to be also an object:
Price {
currency: string;
amount: number;
}
Product {
//…
price: Price
}
Now we start thinking about the relationship between those two concepts: the price and product. How do they relate to each other in our product? Is it a one-to-one relationship, one-to-many?
Price Is Not an Entity
If we change the name of a product, the product is still the same. But if the price changes, is it still the same? No.
Therefore, “price” is not an entity because it has no identification.
We fell into the “primitive obsession” probably because prices have no identification. We understand that a product is an object because it’s tangible and easily identifiable. But the price seems too “small” to have the same level of complexity as a product.
If we only have the concepts of “entity” and “primitive,” then we consider everything that is not an “entity” as a “primitive.”
Value Object
In the book Domain-Driven Design, Eric Evans proposes a new concept called Value Object.
“An object that represents a descriptive aspect of the domain with no conceptual identity is called a VALUE OBJECT” Eric Evans.
We care only about the value of the attributes. Therefore, if the properties change, it’s a new object, not the previous one.
If you were like me, you were falling into the trap of primitive obsession again and again. I recommend you incorporate the concept of Value Object into your developer toolkit.
Value objects are objects with domain meaning but no conceptual identity.
Further reading
If you like this post, consider sharing it with your friends on twitter or forwarding this email to them 🙈
Don't hesitate to reach out to me if you have any questions or see an error. I highly appreciate it.
And thanks to Michal for reviewing this article 🙏