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.
Related
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.
In Domain Driven Design,domain objects are fall into two categories,entity and value object.It is very easy to make out which is entity,which is value object,but i don't know why we have to do that?Before the advent of DDD, we model the domain without entity and value object.After the DDD was put forwar,we use entity and value object to classify domain object, so what is the advantage of such classification?
domain objects are fall into two categories,
Actually, no, objects are a possible implementation of a domain Concept , which is basically just information, not code. A concept can be an Entity because it makes sense to identify it in a uniquely and consistent manner, regardless how it changes over time (e.g: a Customer can change their name but it's the same customer. 2 customers with the same name are not necessarily the same person).
A Value Object (a name that still reminds us that DDD started a bit too coupled to OOP) represent a Domain concept that it's just a value. Or more precisely, the business only cares about its value. If you change it, it's another value all together. Basically, 5 dollars is 5 dollars, you don't really care which is which, any of them is good enough, because only the value is important.
Another thing is, as a domain modeler you identify the nature of a concept based on how the business looks at a concept. The business tells you what they care about.
Now, that we know that a concept can be a Entity, we can select a certain instance of it (User with Id 3). You can't do that with VO, because a VO doesn't have an identity.
Even more, when we identify aggregates, most of the time, the aggregate components (other concepts) are mostly VOs, because they usually are just values (but they do respect business constraints).
So, in conclusion, we classify concepts into Entity and VO, because
The business sees them in this manner: uniquely identifiable or just value
Entities keep their identity regardless how they change (obviously the identity itself is read-only), we treat each one as unique
VO are values that can be used interchangeably, we don't care which is which as long as they represent the same value (which itself, as an implementation detail can be a complex - composite - value). Also, a VO by its nature is immutable, so we know that we can't change it without becoming another value.
Before the advent of DDD, we model the domain without entity and value object.After the DDD was put forwar,we use entity and value object to classify domain object, so what is the advantage of such classification?
You should review Chapter 5 ("A Model Expressed in Software") of the Blue Book.
Evans writes:
Defining objects that clearly follow one pattern or the other makes the objects less ambiguous and lays out the path toward specific choices for robust design.
Tracking the identity of ENTITIES is essential, but attaching identity to other objects can hurt system performance, add analytical work, and muddle the model by making all objects look the same.
... bidirectional associations between two VALUE OBJECTS just make no sense. Without identity, it is meaningless to say that an object points back to the same VALUE OBJECT that points to it. The most you could say is that it points to an object that is equal to the one pointing to it, but you would have to enforce that invariant somewhere.
My own summary would be this: recognizing that some domain concepts are entities is useful, because it encourages the designer to acknowledge that identity, continuity, and life cycle are important concerns for the entity in this domain. Similarly, recognizing that a concept is a value immediately frees you from those concerns, bringing your attention to their immutable nature and equivalence.
I am working on an application where users can follow each other, in a similar fashion to Twitter.
After reading up on DDD, I understand that my users are Entity Objects - I refer to them using their unique ID.
When one user 'follows' another (i.e. forms a Connection), the relationship is stored in a many-to-many table. Its fields include FollowerID, TargetID, and Status. There can be only two records for each Follower/Target combination (one Active, the other Inactive), so I can safely identify objects based on their attributes.
So, I think my Connection objects are Value Objects, not Entity Objects, but I'm not sure. Can you help me with this decision?
You are correct that entities are unique and carry the notion of having an identity (i.e. only one unique user can exist). A Connection is dependent on other User entities. It represents some aspect between two users. That aspect is whether there is an active or inactive connection. Without containing the data of which users are connecting, a connection has no identity. It may even have it's own primary key in the database, but from a domain perspective, it has no identity of it's own.
Therefore, I would say that Connection is a value object.
To support my conclusion, Microsoft.Net Architecting Applications for the Enterprise, page 187, says:
A value object class represents an entity in the domain that mostly
contains data and lives for the data it contains. A value object is
fully identified by a combination of values it contains. An entity
object, on the other hand, has its own life and rich behavior
regardless of the data it contains. Entity objects are usually objects
with a longer lifetime. A value object represents an aspect of an
entity and can live only in relation to an entity.
And also on page 189:
One further comment is needed to explain the difference between
entities and value objects. You don’t need a repository or a data
mapper for a value object. You need a repository only for an entity.
The repository (or the mapper) for a given entity will certainly take
care of all value objects that depend on a given entity.
Some time ago, I saw a cartoon about scientist that had invented cloning. Every time he cloned himself, he destroyed previous version. Then person that was watching demonstration decided to interrupt and sabotaged destruction part so there were two scientists. Cartoon ended with some interesting existential questioning.
Values vs entities is not about having or not having id fields in one or another form. Point is - how we are looking at those objects through our domain perspective. If they are value objects, then only their value matters - 1st, 3rd and 53rd scientist are the same. If we care about identity, if we think that cloning 3rd scientist will never be like 1st one, then our object is an entity.
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.
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