In DDD, what are the actual advantages of value objects? - domain-driven-design

I have gotten so far that I understand entity objects have an ID while value object have not, but in the most common example you have the person entity that have a address value object attached to it. What is the big advantage of creating a separate address object instead of just keeping the address properties within the Person Entity?

In addition to the things already mentioned, Greg Young makes a big deal out of the fact that since they are immutable, you can validate them on creation and never worry about validation again. If the state cannot be changed, then you know it's always valid.

Value objects can be used as arguments for other methods in other classes
It can make your design clearer
It might help with performance optimization (example: fly-weight pattern)
Value objects can be reused in different entities. (example: user and location entities with address value objects.
Don't forget that "not having an id" is not the only difference between value objects and entities, being immutable is also very important.

Think of it as a reusable component. You can make it into a home address, work address without much extra effort. You can use it to decouple other systems from the person entity. Say you introduce a business entity. It will also have an adress.
Related to this subject is another important subject: composition vs. inheritance

Related

DDD: Domain Objects Structure

I'm new to DDD and I want to clearly understand each domain object structure and role:
Aggregate Root:
1.1. The only contact point the client can interact with the domain objects, the client should not be able to modify or create new Entities or value objects whiteout the aggregate root? (Yes/No)
1.2. Can an aggregate root contain only value objects ? for example User root, it contain only address, phone, things which are value objects as far as I understand. So is it a sign of bad design when your aggregate root contain only value objects? shall it contain only entities and via entities interact with value objects?
Entities: Shall the entities contain only value objects? or it can also contain other entities? can you give me a simple example please ?
Value Objects: shall I go ahead and encapsulate every primitive type in an value object? I can go deep and make every primitive type as an value object, for example: PhoneNumber can be a string or an value object which contains country code, number. the same thing can be applied to all other primitive type value such as name, email. So where to draw the line ? where to say "Ok I'm going to deep", or going deep is the right way of doing DDD?
Factories: Do I really need them? I can go ahead and write an static method within the domain object which knows more precisely how to construct it, am I doing wrong ?
Sorry for the long questions, but I'm feeling little lost despite of continues reading, if you can help me I would be glad.
I'll try to answer all your questions:
1.1. The only contact point the client can interact with the domain objects, the client should not be able to modify or create new Entities or value objects whiteout the aggregate root? (Yes/No)
Entities live within ARs and allowing the client to create them would violate encapsulation, so for entities you are correct, ARs create their own entities which don't get exposed to the outside (copies/immutable views could be).
On the other hand, value objects are generally immutable and therefore there's no harm in having them supplied to the AR as data inputs.
In general all modifications needs to go through the AR so that the AR is aware of the modification. In special situations the AR could detect modifications within it's cluster by listening to events raised by internal entities when it's impractical to go through the root.
1.2. Can an aggregate root contain only value objects ? for example User root, it contain only address, phone, things which are value objects as far as I understand. So is it a sign of bad design when your aggregate root contain only value objects? shall it contain only entities and via entities interact with value objects?
Favor value objects as much as you can. It's not unusual for all parts of an AR being modeled as values. However, there's no limitation or law stating whether or not an AR should have only values or entities, use the composition that's fit to your use case.
Entities: Shall the entities contain only value objects? or it can also contain other entities? can you give me a simple example please ?
Same answer as above, no limitation nor law.
Value Objects: shall I go ahead and encapsulate every primitive type in an value object? I can go deep and make every primitive type as an value object, for example: PhoneNumber can be a string or an value object which contains country code, number. the same thing can be applied to all other primitive type value such as name, email. So where to draw the line ? where to say "Ok I'm going to deep", or going deep is the right way of doing DDD?
Primitive obsession is worst than value object obsession in my experience. The cost of wrapping a value is quite low in general, so when in doubt I'd model an explicit type. This could save you a lot of refactoring down the road.
Factories: Do I really need them? I can go ahead and write an static method within the domain object which knows more precisely how to construct it, am I doing wrong ?
Static factory methods on ARs are quite common as a mean to be more expressive and follow the UL more closely. For instance, I just modeled as use case today where we had to "start a group audit". Implemented a GroupAudit.start static factory method.
Factory methods on ARs for other ARs are also quite common, such as var post = forum.post(author, content) for instance, where Post is a seperate AR than Forum.
When the process requires some complex collaborators then you may consider a standalone factory though since you may not want clients to know how to provide and setup those collaborators.
I'm new to DDD and I want to clearly understand each domain object structure and role
Your best starting point is "the blue book" (Evans, 2003).
For this question, the two important chapters to review are chapter 5 ("A model expressed in software") and chapter 6 ("the life cycle of a domain object").
ENTITIES and VALUE OBJECTS are two patterns described in chapter 5, which is to say that they are patterns that commonly arise when we are modeling a domain. The TL;DR version: ENTITIES are used to represent relationships in the domain that change over time. VALUE OBJECTS are domain specific data structures.
AGGREGATES and FACTORIES are patterns described in chapter 6, which is to say that they are patterns that commonly arise when we are trying to manage the life cycle of the domain object. It's common that modifications to domain entities may be distributed across multiple sessions, so we need to think about how we store information in the past and reload that information in the future.
The only contact point the client can interact with the domain objects, the client should not be able to modify or create new Entities or value objects whiteout the aggregate root?
Gray area. "Creation patterns are weird." The theory is that you always copy information into the domain model via an aggregate root. But when the aggregate root you need doesn't exist yet, then what? There are a number of different patterns that people use here to create the new root entity from nothing.
That said - we don't expect the application to be directly coupled to the internal design of the aggregate. This is standard "best practice" OO, with the application code coupled to the model's interface without being coupled to the model's implementation/data structure.
Can an aggregate root contain only value objects ?
The definition of the root entity in the aggregate may include references to other entities in the same aggregate. Evans explicitly refers to "entities other than the root"; in order to share information with an entity other than the root, there must be some way to traverse references from the root to these non-root entities.
Shall the entities contain only value objects?
The definition of an entity may include references to other entities (including the root entity) in the same aggregate.
shall I go ahead and encapsulate every primitive type in an value object?
"It depends" - in a language like java, value objects are an affordance that make it easy for the compiler to give you early feed back about certain kinds of mistakes.
This is especially true if you have validation concerns. We'd like to validate (or parse) information once, rather than repeating the same check every where (duplication), and having validated vs unvalidated data be detectably different reduces the risk that unvalidated data leaks into code paths where it is not handled correctly.
Having a value object also reduces the number of places that need to change if you decide the underlying data structure needs improvement, and the value object gives you an easily guessed place to put functions/methods relating to that value.
Factories: Do I really need them?
Yes, and...
I can go ahead and write an static method within the domain object
... that's fine. Basic idea: if creating a domain object from so sufficient set of information is complicated, we want that complexity in one place, which can be invoked where we need it. That doesn't necessarily mean we need a NOUN. A function is fine.
And, of course, if your domain objects are not complicated, then "just" use the objects constructor/initializer.

UML and Implementation: Associating Classes through IDs

I was recently studying an online course. it was recommended that to reduce coupling we could simply pass the ID from the customer object to the Order object. that way the Order did not have to have a full reference to the Customer class.
The idea certainly seems simple and why pass a whole object if you don't need all its attributes?
1) What do you think of this idea?
2) How would I express the relationship between the Customer class and the Order class in UML if only an ID is passed. This isn't just an example of aggregation is it? Doesn't composition and aggregation require more than just passing a value?
Thanks!
First of all you need to be clear about what UML actually is. On the one hand you have an idea and on the other side there is some code running on hardware. Ideally the latter supports the first in a way that brings added value to a user of the idea. Now, there are many possibilities to describe the way from idea to code. And UML is one of them. It is possible to describe each step on this way but for pragmatic reasons UML stops at the border of code, namely programming languages.
Now for you concrete question: Any object can be seen as an instance. That is some concrete memory partition with a fixed address. Programming languages realize instances by allocating memory and using the start address as reference. And since this reference does not change the object can be identified by its address. Clearly then, an association will just be the a pointer. And an association class will hold two (or more) such pointers.
Honestly, the very first time I started with OO I was also confused and thought that it's a waste of resource to pass those large objects. But since it's just a pointer it's really easy going.
Again, things can get more difficult if you need to persist objects. In that case you need an artificial key you can save along with the object and you will likely need tables to map artificial key to the concrete instance address.
The answer to this question depends on a number of factors, which I started listing in a comment attached to your question. I will assume that you are either using UML to create a Domain Model, or you are describing an implementation done using a statically typed language.
If you are using UML to create a Domain Model, you are obfuscating the semantics when you use an ID to "link" classes. Just draw and annotate the association and you're done.
If you are describing an implementation done using a statically typed language - types exist for a reason. Using generic IDs to link things means that the information that the system needs most become more indirect, and therefore more opaque (which is bad). In your case, the Order object still must acquire a typed reference to a Customer object to do anything with it.
For example, the Order may acquire a reference to the Customer by invoking a lookup by the ID, but it must cast the reference to an appropriate type to invoke anything on the Customer object. So you haven't reduced the coupling from the Order to the Customer. You just buried it somwhere else.

Domain Driven Design - Value object immutable

I'm trying to understand the concept of value object. One aspect of value object is immutable. I would like to know that do we have to implement a thing that manages value object? For instance, Person is entity and Address is value object. Two person have same address.
+ Can we assign the same instance address for each person?
+ How do we know the address already existed so we don't need to create new one?
+ How we manage value object?
I don't whether i understand immutable aspect correct or not. Could you please advice me on this matter?
With reference to Eric Evans' Domain Driven Design: Tackling Complexity In The Heart of Software, a key attribute of value object is that they are often transient (i.e. short-lived), created for a specific operation and then discarded. If you are using programming languages that don't have any built-in automatic garbage collection mechanism (like C, C++), you will have to manually free up their memories at the end of their lifecycle. Otherwise, you shouldn't need any heavy duty implementation to manage them. (Eric Evan talked about garbage collection when comparing Entities and Value Objects too.)
The immutable aspect of value objects simply means that once created, none of their attributes can be modified except by full replacement of the entire object. So if two Person entities shared the same Address value object, and one of them changes her address, a new separate Address value object will be created to represent the new address.
Of course, this is not a die-hard rule. Legitimate cases for mutable value objects include:
If the value objects change frequently,
Their creation and/or deletion processes are computationally expensive,
Their replacement (instead of modification) disrupt the stability of the system,
etc.
Another aspect of value objects is that they have no conceptual identity. But that doesn't mean they can't have low-level identifiers such as a column marked as their primary key in a relational database. Eric Evans also talked about association between entities and value objects. So if you decided to shared an Address value object between two Person entities, you can determine if the address already exists by querying the database, or whatever shared in-memory data structure accessible to the entities.

DDD: Can immutable objects also be entities?

I've read countless posts on differences between Entities and Value objects and while I do think that at least conceptually I understand how the two differ, it appears that in some of these posts authors consider a particular domain concept to be a VO simply because it is immutable ( thus its state will never change, at least within that particular domain model ).
Do you agree that if the state of an object will never change within particular domain model, then this object should never be an entity? Why?
thank you
Do you agree that if the state of an object will never change within
particular domain model, then this object should never be an entity?
Why?
I'd say 90+% of entities will change at some point in their lifetime. But some entities might be unchangeable because of their nature in the domain - a PrepaidPhoneCard, a TransferOrder in a banking system for instance.
Some also like to make their Entities immutable by default because it helps shaping a design that preserves invariants and makes domain operations explicit : http://www.jefclaes.be/2013/04/designing-entities-immutability-first.html
The object could be an entity if you need to identify it.
According to the DDD book, if an object has identity and lifecycle but will not change over time, you could also consider the object as an event.
In two words: yes, they can.
Eric Evans in his book tells about a "thread of continuity" inherent to entities. In layman terms, an entity can be POSTed by a front-end as JSON, get converted into a DTO by a framework, then into a domain object, then into a DTO again and then finally get stored in a database table. During all these transformations the entity will be easily distinguishable because it possesses one or more unique business ids.
With this in mind, aren't some forms of immutability a form of another thread of continuity? Imagine copy-on-write: all of the immutable object's copies are formally different objects representing it at different points of its lifetime. Yet, there is a unique id allowing us to say it's the same entity.
Now, let's talk about the "extreme" form of immutability: read-only objects. Can an entity be a read-only object? Sure, a good example is a credit card statement.
Summing up:
One entity can exist in many forms. In fact, you will almost always have multiple representations of your entity in a program without being aware about it.
A true requirement an entity is an existence of a unique business identity (not a surrogate id that is used for technical purposes) that makes it distinguishable from other entities.
Entities can be immutable, whether we talk about COW or read-only objects.

Value Objects in CQRS - where to use

Let's say we have CQRS-inspired architecture, with components such as Commands, Domain Model, Domain Events, Read Model DTOs.
Of course, we can use Value Objects in our Domain Model. My question is, should they also be used in:
Commands
Events
DTOs
I haven't seen any examples where Value Objects (VO) are used in the components mentioned above. Instead, primitive types are used. Maybe it's just the simplistic examples. After all, my understanding of VOs use in DDD is that they act as a glue for the whole application.
My motivation:
Commands.
Let's say user submits a form which contains address fields. We have Address Value Object to represent this concept. When constructing command in the client, we should validate user input anyway, and when it is well-formed, we can create Address object right there and initialize Command with it. I see no need to delegate creation of Address object to command handler.
Domain Events.
Domain Model already operates in terms of Value Objects, so by publishing events with VOs instead of converting them to primitive types, we can avoid some mapping code. I'm pretty sure it's alright to use VOs in this case.
DTOs.
If our query-side DTOs can contain Value Objects, this allows for some more flexibility. E.g., if we have Money object, we can choose whether to display it in EUR or USD, no need to change Read Model.
Ok I've changed my mind. I have been trying to deal with VOs a bunch lately and after watching this http://www.infoq.com/presentations/Value-Objects-Dan-Bergh-Johnsson it clarified a couple of things for me.
Commands and Event are messages (and not objects, objects are data + behavior), in some respects much like DTOs, they communicate data about an event and they themselves encapsulate no behavior.
Value Objects are not like DTOs at all. They are a domain representation and they are, generally speaking, rich on behavior like all other domain representations.
Commands and Events communicate information into and out of the domain respectively, but they themselves do not encapsulate any behavior. From that perspective it seems wrong and a possibly a violation context boundaries to pass VOs inside of them.
To paraphrase Oren (though he was referring to nHibernate and WCF) "Don't send your domain across the wire".
http://ayende.com/Blog/archive/2009/05/14/the-stripper-pattern.aspx
If you want to communicate a value object, then I suggest passing the necessary attributes needed to re-construct the VO within them instead.
Original Text (for posterity):
If you are asking if Value Objects can be passed by the domain model to events or passed in by commands, I don't really see a huge problem with the former, though the latter may violate some of the rules of the aggregate root being the "owner" of values.
That said a value object represents concepts like for example a color. You don't have green, you are green or not. There seems to be nothing intrinsically wrong with a command telling you that you are green by passing this.
Reading the chapter from DDD on the Aggregate Root pattern explains Entities and Value Objects quite well and is worth reading over a few times.
I say it's a bad idea.
There's a reason we don't do the same with entities - to avoid coupling other parts of the system to the domain (in the wrong places). The same is true for Value Objects, the only difference between value objects and entities is lifetime and ownership - these differences do not affect how we should and should not couple to them.
Imagine that you make an event contain a VO. A change in your domain requires you to change that VO. You've now boxed yourself into a corner where your event is also forced to change, ditto for any Commands or DTO's it's a part of.
This is to be avoided.
Use DTO's and/or primitives. Map them (AutoMapper makes it a 1-line deal).
Similar to other answers, in SOA this would break encapsulation of the service as the domain is now leaking out.
According to Clean Code your DTOs are data structures (just to add another term), while value objects are objects. The difference that objects can have behavior. Mixing data structures with objects is generally a very bad idea, because it will be hard to maintain the hybrid you get.
I don't feel right to put value objects to DTOs from an architecture perspective as well. The value objects are inside of the domain model while the DTOs you mentioned are defining the interface of the model. We usually build an interface to decouple the outside world from the inside of something. So in the current case we added DTOs to decouple the outside world from the value objects (and other model related stuff). After that adding value objects to the interface is crazy.
So you haven't met this solution yet because it is an anti-pattern.
Value Objects are or at least should be immutable. Once instantiated with a value that value will never change throughout the lifetime of the object. Thus, passing VOs as data to DTOs (such as Events) should not be an issue since all you can do with them is get their value. At the most their value in a differing representation such as toString() as opposed to an original getValue() which might return an integer or whatever the value is.

Resources