A Value Object is a small object that represents a simple quantity, such as a sum of money, a date, or a range of cells. Its identity is based on its value rather than on a unique identity.
What defines a Value Object is that two instances are considered equal if they have the same value, regardless of whether they are the same object in memory.
# When to use it?
It is ideal for representing domain concepts that do not require a persistent identity but group related attributes that always go together (such as an Address or an Amount).
# Pros
-
verified
Immutability
They are generally immutable, which prevents unwanted side effects.
-
verified
Semantic Clarity
Adds meaning to the code by grouping related data under a descriptive name.
-
verified
Ease of Testing
Being immutable and having no dependencies, they are very easy to test.
# Cons
-
warning
Memory Overhead
Creating many small objects can slightly impact performance in extreme cases.
-
warning
ORM Difficulty
Some object-relational mappers may require extra configuration to handle them.
# Detailed Example in Java
A classic example of a Value Object to represent Currency:
Money.java
public final class Money {
private final BigDecimal amount;
private final String currency;
public Money(BigDecimal amount, String currency) {
this.amount = amount;
this.currency = currency;
}
public BigDecimal getAmount() { return amount; }
public String getCurrency() { return currency; }
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Money)) return false;
Money money = (Money) o;
return Objects.equals(amount, money.amount) &&
Objects.equals(currency, money.currency);
}
@Override
public int hashCode() {
return Objects.hash(amount, currency);
}
}
# Conclusions
The Value Object pattern simplifies business logic by treating small objects as immutable values rather than entities with complex life cycles. This improves the robustness and maintainability of the system.