10

I'm reading "Patterns, Principles, and Practices of Domain-Driven Design". The book suggests that properties of an Entity should be value objects in order to model domain's ubiquities language. I've seen many examples like EmailAddress or Age with only one field to model domain concepts. I'm confused about it. Is every property of an Entity a value object? Can you provide examples when we can use normal languages provided data types for properties?

Majid Azimi
  • 5,575
  • 13
  • 64
  • 113
  • 2
    You never HAVE TO use value objects instead of primitive values, but abusing value objects is certainly better than the opposite. If you think a String is enough to represent a business concept that's perfectly fine. – plalx Oct 26 '15 at 18:56

2 Answers2

14

No, not every property of an entity is a value object.

Properties of entities are one of the following:

  • As you already know, value objects. Value objects represent simple values without identity.
  • Primitives. These are just value objects from a DDD perspective, really. Primitives are ok to use in DDD, but take care not to become a victim of Primitive Obsession.
  • Entities. An entity can contain other entities. All entities that have direct (navigable) references between them are part of the same Aggregate. The "top-most" entity within an aggregate is called the Aggregate Root. Only the root has a global identity, inner entities have only local identity.
  • References to entities of other aggregates. Never reference these directly, use an ID. IDs themselves can in turn be modeled as value objects.
theDmi
  • 17,546
  • 6
  • 71
  • 138
4

I think that your real question is: Is every value object a Class? Because you can think that for the Age a Java Integer can be enough and this is true. So you have in your entity Person a value object Age of type Integer, there is no need of an age type.

OOP also says that an object is state + behaviour. In your Age case, I assume that it has no behavior so a simple primitive or wrapper class will do the trick, in fact I would go with option this because is simpler.

My advise is, go with a primitive/wrapper class and if you advert that some behavior is needed in that value object, make a class/type.

gabrielgiussi
  • 9,245
  • 7
  • 41
  • 71
  • So for one-field-value-objects the point is: Do we have any behaviour associated with it? If the answer is yes then it is a good idea to create a class for that property. Is my understanding correct? – Majid Azimi Oct 26 '15 at 19:00
  • 3
    @MajidAzimi I would say behavior/validation would form a better guideline. For instance, an `Age` can never be negative in any context and must be an integer value. It would make sense to encapsulate that constraint in an `Age` value object. – plalx Oct 26 '15 at 19:43
  • 3
    I don't think that validation is enough to justify a class. The entity must be valid as a whole, this validation also validates the value objects that integrate the root entity. When the turn of validate the ages arrives, it would be a simple > 0 or JSR 303 Annotation. – gabrielgiussi Oct 26 '15 at 19:52
  • 4
    @gabrielgiussi Validation annotations do not have their place in the domain, that's for view models. Models should be free of any kind of infrastructure dependencies. **Do not forget that the essence of DDD is the ubiquitous language, not the technical implementation**. `Age` is a business concept with rules revolving around it. The invariants of `Age` have nothing to do with the entity to which it is associated to. For instance, you may have an `Age` concept preventing negative values, but a `Person` entity which prevents being older than 125 years old. – plalx Oct 26 '15 at 21:29
  • 1
    There's no to very little cost to be explicit and the design will be much more supple that way. For instance, what if `Age` is a concept needed somewhere else in the design as well? At that point you would have to extract the rules in a VO anyway and then change your contracts. – plalx Oct 26 '15 at 21:34
  • 1
    Yes @plalx, I agree that in some cases a separate class is a good alternative, obviously each case has to be properly evaluated. What I propose is go from the [SimplestThingThatCouldPossiblyWork](http://c2.com/xp/DoTheSimplestThingThatCouldPossiblyWork.html) – gabrielgiussi Oct 26 '15 at 22:37
  • I'm definitely in discord with you are saying about no put validation annotations in the domain. In fact the [JSR 303](https://jcp.org/en/jsr/detail?id=303) specification says **The validation API developed by this JSR will not be specific to any one tier or programming model. It will specifically not be tied to either the web tier or the persistence tier** – gabrielgiussi Oct 26 '15 at 22:40
  • 1
    Although I am no fan of attributes in the domain I *do* agree that validation may not be the deciding factor to make something a VO. An `Age` value object may not be all that useful if there is no behaviour other than validation. Voting `Age` could have a minimum of 18 years, Insurance `Age` from, say, 16 to 65, whereas somebody's `Age`, in general, has a minimum of around zero :) --- In a broader sense one *could* say that a validation class is a type of value object but not in the sense typically used in DDD. – Eben Roux Oct 27 '15 at 04:46
  • @EbenRoux There's a shared common invariant around `Age` in all the contexts you mentionned. It can never be negative. That's what an invariant is, it's not context-dependent. The minimum age for a `VotingRight` may be 18, but that has nothing to do with the `Age` concept itself. – plalx Oct 27 '15 at 12:44
  • @gabrielgiussi Perhaps this will help understanding my point of view on annotations: http://stackoverflow.com/questions/28395176/should-i-abstract-the-validation-framework-from-domain-layer/28397201#28397201 – plalx Oct 27 '15 at 12:52