Depending on the context certain concept may be modeled as an entity or as a value. It could be both in different bounded contexts. To me, good heuristics to choose between entities and values are life cycle and mutability. Values are immutable, represent constants. A color is a good example (thanks Alfredo). If color changes from red to blue it’s not the red color anymore but something else. The cost of returning a new instance when color changes is cheap:

Color yellow = red.mixWith(green);

When returning a whole new objects costs many lines of code and memory that could be a sign that it’s probably better modeling as an entity. If we care about changes that could be another sign. Recently we had to model a draft invoice. From the point of view of the business a draft doesn’t require a unique number, only the final invoice has to have a unique sequential number (identity). So I thought we could model the draft as a value. After all if two drafts consist of the same customer and the same lines, the business could not tell the difference between the two. We chose a value object but then every time a new line went into the draft we had to create a new one, copying all the existing lines. Too much code for such a simple operation. Finally we changed the design modeling the draft as an entity.

Questioning the design made us speak to the domain experts – “how would you search for a certain draft? If two draft contains exactly the same how do you differentiate them?”. And they decided the application should allow for just a single draft per customer. It simplified the application even though eventually we used an entity.

As the object changes, we may be interested in tracking why, who and by whom changes were made” – This is a good heuristic to think of an entity.

When the entity’s identity generation is delayed until it’s persisted, we might have to implement the equals and hashCode methods as if it was a value object to avoid bugs”. This kind of workarounds make the distinction fuzzy.

I currently think that choosing an entity or a value boils down to good object oriented and simple design. Value objects are older than DDD, I believe the term was coined by Ward Cunningham. Even if the object is an entity, I try to avoid getters and setters as much as I can. Rather than reading information from object properties, objects may communicate with each other by sending messages.

Things to remember from the two chapters:

  • I like the trick of Layer Supertype on page 187 to hide a surrogate identity from entity’s consumers.
  • I find the idea of “role interfaces” on page 203 quite handy to expose only certain behavior to consumers.
           class Customer : AddOrder, MakePreferred {
                    …
           }

           var customer = Repository.Find<AddOrder>(customerId);
           customer.AddOrder(order);
  • Values advantages: “Value types that measure, quantify or describe things are easier to create, test, use, optimize and maintain”
  • Limit a value to depend on and understand its own type and the types of its attributes.
  • Pass only values as parameters to value methods.
  • I like how he uses the Java enum to implement the State pattern on page 235 (he calls it Standard Type). Java enums are really powerful.