value-object/README.md
The Value Object pattern in Java creates immutable objects that represent a descriptive aspect of the domain with no conceptual identity. It aims to enhance performance and reduce memory overhead by storing frequently accessed immutable data directly within the object that uses it, rather than separately.
Real-world example
Consider the case of a business card. In our example, a BusinessCard class is implemented as a Value Object to demonstrate immutable data handling and efficiency in Java applications. In the real world, a business card contains information such as the person's name, job title, phone number, and email address. This information represents a specific and complete set of attributes describing the contact details of an individual but doesn't have an identity itself beyond this information.
In a software system, you can create a
BusinessCardclass as a Value Object. This class would be immutable, meaning once aBusinessCardobject is created with a person's details, those details cannot change. If you need a different business card, you create a new instance rather than modifying the existing one. The equality of twoBusinessCardobjects would be based on their contained data rather than their memory addresses, ensuring that two business cards with the same details are considered equal. This mirrors how business cards in real life are used and compared based on their content, not on the physical card itself.
In plain words
Value objects are equal when their attributes have the same value.
Wikipedia says
In computer science, a value object is a small object that represents a simple entity whose equality is not based on identity: i.e. two value objects are equal when they have the same value, not necessarily being the same object.
Flowchart
There is a class for hero statistics in a role-playing game. The statistics contain attributes such as strength, intelligence, and luck. The statistics of different heroes should be equal when all the attributes are equal.
Here is the HeroStat class that is the value object. Notice the use of Lombok's @Value annotation.
@Value(staticConstructor = "valueOf")
@ToString
class HeroStat {
int strength;
int intelligence;
int luck;
}
The example creates three different HeroStats and compares their equality.
public static void main(String[] args) {
var statA = HeroStat.valueOf(10, 5, 0);
var statB = HeroStat.valueOf(10, 5, 0);
var statC = HeroStat.valueOf(5, 1, 8);
LOGGER.info("statA: {}", statA);
LOGGER.info("statB: {}", statB);
LOGGER.info("statC: {}", statC);
LOGGER.info("Are statA and statB equal? {}", statA.equals(statB));
LOGGER.info("Are statA and statC equal? {}", statA.equals(statC));
}
Here's the console output.
20:11:12.199 [main] INFO com.iluwatar.value.object.App - HeroStat(strength=10, intelligence=5, luck=0)
20:11:12.202 [main] INFO com.iluwatar.value.object.App - HeroStat(strength=10, intelligence=5, luck=0)
20:11:12.202 [main] INFO com.iluwatar.value.object.App - HeroStat(strength=5, intelligence=1, luck=8)
20:11:12.202 [main] INFO com.iluwatar.value.object.App - Is statA and statB equal : true
20:11:12.203 [main] INFO com.iluwatar.value.object.App - Is statA and statC equal : false
Use the Value Object when
Benefits:
Trade-offs: