Tue Dec 23, 2003 8:52 am
In New York City, the Design Patterns Study Group is looking at Eric's
"Domain Driven Design" right now. We meet every Monday to discuss
patterns-related topics, and we had some discussions last night about
chapters 5 and 6 of the book. The group came up with the following
question that perhaps Eric or someone else might answer for us;
There are
ValueObjects,
Services, and
Entities. What is there besides
ValueObjects,
Entities and
Services? In chapter 6, it's mentioned
that a
Factory might be something that's not a
ValueObject/
Entity/
Service. What about a "configuration" object, storing,
say a configuration of a mailer. It's definitely something that might
have "get/set" methods and is NOT immutable, so perhaps it's not a
"
ValueObject" (or is it?) - on the other hand, it's something that's
described by its parameters rather than something that has an intrinsic
"identity" so perhaps it's not an "
Entity" either?
Perhaps we are just splitting hairs, but we felt that if we should at
least agree on a terminology. Does anyone else have any thoughts on
this topic?
Thanks in advance!
GeneVolovich
I see almost everything as
ValueObjects, because I'm a Test-Driven
Design practitioner. Everything's a
ValueObject because I often use
assertEquals() to compare expected and actual values in my tests. It's
the most frequent type of assertion I make. I'm using the term "
ValueObject" perhaps loosely, defining them as objects that obey value
semantics when compared to one another.
For me, an
Entity (I call it a Domain Object) is a
ValueObject with an
identity. The identity is just another property of the underlying
ValueObject for comparison purposes. Therefore, two
Entities are equal if
they have the same values and the same ID.
A
Service, then, is essentially anything not a
ValueObject: it operates
on value objects and answer value objects, but isn't one itself. A
Service is typically /only/ the return value of either a
Factory or a
Repository.
That's a rather clouded look at my rather clouded view of things. Note:
I haven't made it through the book, yet. I have to figure out how/when
to finish my own first. :)
JBRainsberger
I think of value objects (mutable and immutable), entity objects, and
"Other" including "stateless" objects...
For example, a "configuration object" may be a platform-independent
wrapper for the Registry API on Windows, the User Defaults API on MacOS
X, and reading/writing ~/.somefile on unix/linux. None of the
platform-dependent versions of this object necessarily need to have
their own state, though caching the state might be useful if profiling
determines that there's too much overhead in using the native APIs all
the time. I like the stateless object for this particular case, because
we can have many of them, possibly in multiple threads, without having
to synchronize them -- the APIs we're calling are already synchronized
(at least on Windows and MacOS X). Being a normal object, we can pass
around Mock versions in our tests.
Note that a generic preferences object would not be in the Domain layer
- it would be part of the infrastructure layer.
Eric does mention Policy objects as stateless objects implementing the
Strategy pattern in examples of the freight-routing model; these would
neither be Value objects nor Entity objects, as far as I can tell, but
they would reside in the Domain layer.
KeithRay
Two points, explained below:
-the book is mostly about the domain layer
-entities and values only apply to software based on a model
One thing I'll point out is that my book mostly focuses on the domain layer.
The example of a "configuration" object would be in the application layer.
The concepts of entities and value objects can be applied in those other
layers. For example, the printer driver in Windows operating systems is an
entity representing the state of the physical printer and the queue of print
jobs waiting for it. There are lots of value objects in the infrastructure,
application and UI. But, my book is mainly aimed at the domain layer.
Even within the domain layer, there are elements other than value objects,
entities and services. There are factories and repositories, which provide
access to the entities and value objects. There are purely technical
elements that do things like notify of events or talk to the database
mapping layer.
The entities, value objects and services are important in that they are the
main elements that express the domain model. Even there, they are not
necessarily entirely alone. There are objects like policies, which could be
viewed as value objects, but may not always really fit that. But it is those
three that do the heavy lifting.
JB pointed out that value objects are good for testing. I agree. This is one
reason that, in my more mature designs at least, the value objects tend to
carry most of the complex logic. The entities can then be focused on the
issue of continuity and identity, which is often tricky. Value objects have
a meaningful "equals" operation (whether implemented or not). Entities have
a "same" operation instead. Providing an equals on an entity is not a good
idea, because there could be two instances of the same entity that have
different attributes. For example, if a customer changes an address, that
change might not instantly be reflected throughout a distributed system or
(more likely) in another system that is also used in customer relationships.
The customer in the billing system is the "same" as the customer in the
sales support system, even though they are not "equal".
Coming back around to the configuration object, I don't think it is an
entity or a value in the likely designs I can imagine mostly because it is
not part of a *model*. It is just a software mechanism that does a job. If
the application included a model of the application itself, then elements of
the configuration be viewed as attributes of the application's installation.
Then I suppose the installation could be an entity, and most of the
configuration info would be values describing the state of that entity. But
has anyone ever written a configuration system that way? Models should only
be applied where they are useful.
EricEvans
Hi Eric,
I just bought your book and I enjoy reading it (I havent finished it
yet)!
I also have a question about Entities versus Values. Although your
explanation about the differences between the two is very clear to
me, I had some problem reasoning about it determining on my own in
your Cargo example at p169 what an Entity is and what a Value is.
In your example you use the argument whether these objects can be
interchanged in reallife. If not, they must be entities. Argueing
this way, I think it would typically be something that the domain
expert would have to decide whether the object is an entity or not.
However, my experience is that domainexperts don't really look at
the objects this way. They talk more in terms of uniqueness, for
instance I can determine the customer by it's ID, or the color the
pencil has. If two customers have the same ID, they can be
interchanged, if two pencils have the same color, they can be
interchanged.
Looking at Delivery Specification, you argue that two Delivery
Spefication with the same Location object can be interchanged. To me
this complicates matters, because now I have to look at the
relations the object has, to see whether it can be interchanged. The
same difficulty arises when discussing 'Handling Event'. You argue
because they reflect real-world events, they can not be
interchanged. But I could have the same argument about Delivery
Specification, it represents a real-world goal.
Nor does the immutable property help me very much. For instance
having an value object address which attributes, eg. streetname,
cant be changed, but on the other hand, I am allowed to replace it
with an Address Object with a different streetname, which has the
same endresult (on a conceptual level, not on an implementation
level).
So in my opinion, although there is conceptual difference between
the two, the user or domain expert doesnt benefit from it
formulating it this way nor gives it a better understanding of the
domain.
On the other hand, you use the difference (actually the immutable
property) to have a difference in implemenatation. A developer can
either reference a value object or make a copy of it, thus fine-
tuning between resource usage. To me, combining these aspects, that
is difference in semantics and difference in implementation, also
muddles the concept. What I mean is, since I find it hard to
determine the difference at the conceptual level I use the
implementation difference to give the object the right semantics,
which is strange.
To handle the above concepts / problems, I currently do the
following:
- At domain level, I want to know whether the user wants to 'track'
an Object. I can imagine a conversation with the domain expert
asking him 'if you have a bunch of Handling Events, would you want
to track them or distinguish them as individual events' (in this
case yes). On the other hand, asking the same question for delivery
specification, the answer would probably be that Delivery
specifaction is only interesting as a part of Cargo (even if it
there was a one to many relationship between Cargo and DS). Same
applies for Delivery History. This analysing leads to determining
the boundaries of an aggregate. Another question in this case would
of course be whether the object has an existence of it's own. (you
use the 'tracking' word for determining entity versus value);
- For implementation level I want to know whether an object can be
marked as immutable. The immutable property will be based on aspects
like: The frequence at which attributes will change (eg the address
of someone will probably not change a lot), whether the object
references other objects and if so, if these referenced objects can
be marked as immutable, whether there will be a lot of instances
which are 'equal', etc.
Maybe I should rethink the concept of Entity vs Value to better
understand it and how to apply it, maybe it becomes clear to me when
reading further;)
kind regards,
ChristiaanDesBouvrie
A big part of the point is that conceptual modeling and implementations
decisions are not independent of each other and should not be overly
separated. But they are not the same thing, either, so it requires a little
extra care to maintain the subtle and important distinction, while juggling
them both.
Entities and value objects are patterns that cluster characteristics that
can and do appear in objects in many combinations. What the pattern says is
that most of those combinations should be avoided in favor of these two,
that the choice should be driven by the understanding of the domain, and
that the consequences of the choice determine many implementation issues.
While objects can have all sorts of combinations of mutability, trackable
identity, and representation, there is a *modeling* difference between
values and entities. Domain experts can understand the difference.
You say:
> If two customers have the same ID, they can be
> interchanged, if two pencils have the same color, they can be
> interchanged.
No, if two customers have the same ID, you have a corrupted database. (But
you're right about the pencils.)
The example of the HandlingEvent is good for discussion because it is
plausible to consider it as a value. I decided to model it as an entity, in
spite of the fact that its information would never change (except for error
correction). Different people might refer to an event (the actual occurance,
not the data object) and would use its time and place to identify it, but
that would not be considered "it". For a value object, the attributes are
"it".
Chapter 10, "Supple Design", goes further to show how useful the development
of value objects can be.
EricEvans
I guess this explanation is what causes the confusion. I agree there
is a tight relationship between domain model and implementation. But
I also think there should be a clear distinction between decisions
based on the domain (having implications on the implementation of
course) and those solely based on the implementation (maybe
reflected in the model). 'having a corrupted database' is a 'system'
or 'implementation' kind of way of explaining interchanging isnt
valid (maybe I used the word interchange wrong). Maybe I should
clarify this with an example. Suppose you have the concepts or
objects 'Customer', 'Address' and 'Red Pencil'. Answering the
interchange question for the real-world (or domain) point of view
would be:
- Customer: a customer cannot be interchanged, because you know
which customer you are dealing with by it's physical (materialized)
form. It is not possible to have another 'same'customer, because
there is only one person;
- Address: same argument, there is only one physical location with
this address. There is no interchanging from locations because each
location is unique;
- Red Pencil: every red pencil is unique in it's physical form.
However a user of a red pencil can be indifferent whether he or she
uses red pencil 1 or 2.
Same argument hold for not materialized things, such as events. This
only occurs at one unique location at one specific time.
From a real-world point of view, the one the domain expert has to
deal with, interchanging is merely a question of whether the domain
expert can see two different unique things as the same based on
equal attributes.
Answering the question from a system or implementation point of view
is different, because a 'thing' can always have multiple occurences
(not just one materialized form as in the real world). For instance,
in the user interface I can have two screens both presenting the
same customer object (or a print on paper). How can the user
determine they are the same? Having a thick client, there are
multiple instances of the same customer object in the cache of
different clients. At database level, two independent systems (eg.
sales and ordering), can each have a record to represent the
customer (maybe as you described in your book representing in
different ways). Maybe there are duplicates in the same database for
performance reasons (of course this is not preferred and at database
level uniqueness should be preserved by a single instance). To
determine which thing is which (and take actions accordingly, such
as synchronizing differrences using versioning) you have to
determine which attributes make it unique. If these attributes do
not exist, you have to make up an attribute which makes it unique.
(that's what I meant with when two uniqueing attributes are the
same, they must be the same and therefor can be interchanged, or
treated accordingly).
The difference to me is that in the first point of view the domain
expert can answer the question, which gives it meaning in the
domain. Basically everything is unique (entity) and the domain
expert should answer whether different entities can be treated the
same based on some corresponding attribute value and thus making it
a value. From the second point of view, it is a concern of the
system / implementation how to determine the uniqueness of things
(and take actions accordingly) which gives it meaning in the system.
The second point of view is not a difference of value vs entity, but
merely finding unique attribute(s) and if these attributes do not
exist, invent one (But does this make it an entity??), which is to
me a straightforward process.
regards,
ChristiaanDesBouvrie
I see almost everything as Value Objects, because I'm a Test-Driven
Design practitioner. Everything's a Value Object because I often use
assertEquals() to compare expected and actual values in my tests. It's
the most frequent type of assertion I make. I'm using the term "Value
Object" perhaps loosely, defining them as objects that obey value
semantics when compared to one another.
For me, an Entity (I call it a Domain Object) is a Value Object with an
identity. The identity is just another property of the underlying Value
Object for comparison purposes. Therefore, two Entities are equal iff
they have the same values and the same ID.
Yes, you are using the term too loosely. For one thing,
a Value Object should be immutable, so just implementing
the equal operation is not enough to make something a
Value Object. An Entity is most certainly not a Value
Object with something added. For example, when you pass
an object as a value in a distributed system, you can
serialize the Value Object and make a copy of it on the
other side, but you have to make a proxy for an Entity
or else do full object migration with forwarders etc.
In Smalltalk, all objects respond to both "=" and "==".
The first is "equal", and the second is "identical".
The default defininition of "equal" is "identical", and
if you have a real value object then you override "=".
You also must override the "hash" method, and not doing
that is a common bug. The "code critic" that comes with
the Refactoring Browser will tell you if "hash" is missing,
but it won't tell you if you implemented it wrong, and it
doesn't check that the class is immutable. It would be
fairly easy to add a check for immutability. Then we
could make "value objectness" be a first-class quality,
one that is enforced by the programming environment.
I teach people to generally use = and not ==. To me,
== is an implementation detail. Objects should always
know how to compare themselves with each other. I should
be able to ask if any two objects are equal and get a
reasonable answer. Is this process equal to this number,
or this Employee, or this window, or this string? The
answer is "no", of course, but I should get a reasonable
answer. Therefore, saying that a value object is an object
that responds to = makes "value object" a meaningless name.
We already have a name for something like that. We call
it "Object".
RalphJohnson
...
> Yes, you are using the term too loosely. For one thing,
> a Value Object should be immutable, so just implementing
> the equal operation is not enough to make something a
> Value Object. An Entity is most certainly not a Value
> Object with something added. For example, when you pass
> an object as a value in a distributed system, you can
> serialize the Value Object and make a copy of it on the
> other side, but you have to make a proxy for an Entity
> or else do full object migration with forwarders etc.
I'm not sure /why/ all this extra stuff is needed, but then, I haven't
finished reading the book yet, so that may explain my uncertainty. I
suspect that my notion of Domain Object is quite different from Eric's
use of the term Entity.
<snip />
> Therefore, saying that a value object is an object
> that responds to = makes "value object" a meaningless name.
> We already have a name for something like that. We call
> it "Object".
But that's not what I said, Ralph: I used Value Object to refer to an
object that responds to #= with /value equality semantics/ rather than
/object identity semantics/ (that is, forwarding to #==).
JBRainsberger
Domain Question: Do you care if your working with a copy or the original?
If no, it's a Value Object (excluding Service, Policy, Factory ane
Repository). If yes, it's an Entity Object?
DaveFord
> Domain Question: Do you care if your working with a copy or the original?
> If no, it's a Value Object (excluding Service, Policy, Factory ane
> Repository). If yes, it's an Entity Object?
Yes, that is a useful rule of thumb. That gives you a good clue where it
belongs.
Beyond that, the esence of the two patterns is the kind of concept you are
defining. Is it a descriptive characteristic of something or is it an
attempt to track something?
EricEvans
By the way Eric, I am teaching a five day workshop on Object Oriented Design
and Patterns. I have found your domain-centric patterns so useful, they are
now a standard part of my workshop, at least up though Part III. The
students also find the domain centric pattern language helpful. Hopefully,
you'll get some book orders out of it :)
Also, students are asking the difference between DAO and Repository. Good
thing we had that discussion last week.
Thanks again for a great book!
DaveFord
TerminologyQuestionOnValueObjectsAndEntities is mentioned on: ThreadView