Entities, Value Objects, Aggregates and Roots

Taking a small detour before I deliver the first installment in the Domain-Driven Design: Supple Design Patterns series, I’d like to cover the basic elements of Domain-Driven Design modeling:

  • Entities
  • Value Objects
  • Aggregates and Roots

I’d like to cover these aspects partially because these ideas play a large role in the later ideas, but also because Rob asked me to (see comments).  If you’d like an in-depth discussion of these topics, just check out Eric Evans’ Domain-Driven Design, chapters 5 and 6.


From Evans:

Many objects are not fundamentally defined by their attributes, but rather by a thread of continuity and identity.

In traditional object-oriented design, you might start modeling by identifying nouns and verbs.  In DDD modeling, I try to key in on terms coming out of our Ubiquitous Language that exhibit a thread of identity.

For example, consider a Person concept.  If I have two Person objects, with the same Name, are they same Person?  Bob Smith from Cheyenne, Wyoming and Bob Smith from Tallahassee, Florida might not agree.  A popular gimmick I’ve seen is interviewing a Person with a famous name (but different identity).  So if Name isn’t a Person’s distinguishing attribute, what is?  Address?  Social Security Number?  Not for non-US citizens, what about a Kiwi Bob Smith?

In each of these examples, a Person is identified by more than their attributes, such as Name, Address, PhoneNumber, etc.  A Person has a unique identity that manifests itself if different ways in different systems.  Each system has their own attributes they’re concerned with, but the Person is always the same entity (not class, that’s different).

My “litmus test” for Entities is a simple question:

If two instances of the same object have different attribute values, but same identity value, are they the same entity?

If the answer is “yes”, and I care about an identity, then the class is indeed an entity.  I model entities with reference objects (classes), and I give them a surrogate identity (i.e., probably a GUID).  Additionally, my model must include what it means to have the same identity.  That means overriding Equals, looking solely at the identity and not attributes.

Value Objects

From Evans:

Many objects have no conceptual identity.  These objects describe characteristics of a thing.

When I don’t care about some object’s identity, I carefully consider making the concept a value object.  For example, if I have a system that models Paint buckets, the Color is a great candidate for a Value Object.  I care about one specific PaintBucket or another, as I paint with individual PaintBuckets that will eventually be drained of their paint.

But when checking the Color of a specific PaintBucket, the Color has no identity in an of itself.  If I have two Colors with the exact same pigmentation values, I consider them to be the same.

When designing Value Objects, I want to keep them away from the trappings of Entity life cycles, so I make the Value Object immutable, and remove any concept of identity.  Additionally, I’ll override Equals to compare attributes, so that attribute equality is represented in my model.

By making my Value Object immutable, many operations are greatly simplified, as I’m immediately led down paths to Side-Effect Free Functions.  I don’t create a type with a bunch of read-write properties and call it a Value Object.  I make it immutable, put all of the attributes in the constructor, and enforce attribute equality.

Value Objects, like any other pattern, can be over-applied if you go hunting for opportunities.  Value Objects should represent concepts in your Ubiquitous Language, and a domain expert should be able to recognize it in your model.

Aggregates and Roots

In real life, many concepts have relationships to each other.  I have a set of credit cards, and each credit card has an owner (me).  Each credit card has a billing institution, and each banking institution has a set of credit accounts, each of which may or may not be a credit card.  If I were to represent all of these concepts as classes, what would the relationships be?

Should I represent every conceivable relationship possible in my object model?  Where do I draw the line between whether or not to create a reference?  If I have a reference between two entities, how should I handle persistence?  Do updates cascade?  Suppose an Employer has reference to their Manager directly.  If I change the Employee.Manager.Name, and save the Employee, does the Manager’s Name get changed?

Object modeling is complex as it is.  Invariants need to be enforced not only in an Entity, but in all the Entities that are referenced as well.  That gets tough to maintain, and quick!

Aggregates draw a boundary around one or more Entities.  An Aggregate enforces invariants for all its Entities for any operation it supports.  Each Aggregate has a Root Entity, which is the only member of the Aggregate that any object outside the Aggregate is allowed to hold a reference to.  From Evans, the rules we need to enforce include:

  • The root Entity has global identity and is ultimately responsible for checking invariants
  • Root Entities have global identity.  Entities inside the boundary have local identity, unique only within the Aggregate.
  • Nothing outside the Aggregate boundary can hold a reference to anything inside, except to the root Entity.  The root Entity can hand references to the internal Entities to other objects, but they can only use them transiently (within a single method or block).
  • Only Aggregate Roots can be obtained directly with database queries.  Everything else must be done through traversal.
  • Objects within the Aggregate can hold references to other Aggregate roots.
  • A delete operation must remove everything within the Aggregate boundary all at once
  • When a change to any object within the Aggregate boundary is committed, all invariants of the whole Aggregate must be satisfied.

That’s a lot of rules!  All of them just come from the idea of creating a boundary around our Aggregates.  The boundary simplifies our model, as it forces us to consider each relationship very carefully, and within a well-defined set of rules.  Maintaining bi-directional associations is difficult enough without persistence thrown into the mix, so by modeling our relationships around real-world use cases, we can greatly simplify our model.

Not all relationships need to be represented through associations.  In the Employee/Manager relationship, I can have a Manager directly off the Employee, but to get a Manager’s DirectReports, I’ll ask the EmployeeRepository.  Since Employee is an Aggregate Root, it’s fine to have an Employee reference its Manager.

Modeling and simplification

One of my favorite quotes from Evans’ book is:

Translation blunts communication and makes knowledge crunching anemic.

To avoid translation, we’ll represent real-world concepts in our conceptual model, and our conceptual model expressed as code through Entities and Value Objects (and Services).  To simplify our model, we’ll use Aggregates and Roots, enforcing invariants at each operation.  In all cases, I should be able to represent our conceptual model in our code, and it should make sense to our domain expert, as they’ll see the Ubiquitous Language represented.

When the conceptual model we create with the domain expert is realized effectively in code, we’ll find that not only to technical refactorings become easier, but enhancements to our model as well.  Entities and Value Objects are but a slice in the DDD world, but a core concept which many other ideas are built upon.

About Jimmy Bogard

I'm a technical architect with Headspring in Austin, TX. I focus on DDD, distributed systems, and any other acronym-centric design/architecture/methodology. I created AutoMapper and am a co-author of the ASP.NET MVC in Action books.
This entry was posted in DomainDrivenDesign. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • Jimmy, would you mind if I translate this post to spanish and repost it in my blog with your credits?

  • Awesome post; a great summary of the concepts :)
    Looking forward to the future posts on DDD.

  • @Mario

    Go for it! I’d do it myself, pero yo hablo español solo muy poquito.

  • Good stuff. I prefer to ask myself the reverse of the identity question, which reads like:

    If 2 objects have the same exact attributes, are they the same entity?

    In the case of the 2 Bob Smith’s, even if those are the only attributes you currently store, the concept of identity still holds. ie: There is a distinguishing set of attributes that is more exhaustive than our subset in the domain that can uniquely identify an entity. If this fits, then you have an entity. If not, then it’s a value object.

    Money, map routes, commands, etc are all good examples of value objects. You wouldn’t care which instance of the 5 dollars you had, you just care about the value.

  • I do not understand one thing about aggregates. If I have an advanced O/R mapper that tracks changes to Employeee.Manager.DirectReports and lazy-loads it if required, do I really need to make such traversal forbidden?

  • @Andrey

    No, not necessarily. No matter what, bidirectional associations are tough to manage, and you can’t rely on your ORM to do it for you.

    For example, suppose you do something like Employee.Manager.DirectReports.Remove(Employee). Who is Employee.Manager now? When does DirectReports get updated, automatically when I change the Manager?

    I like to drive associations strictly through stories and scenarios, and allow some associations to be done through the Repository. Something like EmployeeRepository.FindDirectReportsFor(Manager). Eventually, you’ll have to manage associations strictly through your Entities.

  • foobar

    Really? You’d still require an instance of a manager to get its employees? I certainly hope not.

  • @foobar

    I assume you’re talking about the difference between:





    Design of this would definitely be driven by use cases and actual stories. I would go with whatever made sense. Hard to say one is always right or not, always “it depends”

  • When using aggregates in real world, I sometimes come across cases where the root entity seems to differ based on the usecase i am looking at. Have you come across any such cases?

    >>Nothing outside the Aggregate boundary can hold a reference to anything inside
    I sometimes have seen need for some shared objects that do not logically belong to one root but rather to two. In such cases, it was more easier to let the shared object be referred by both roots.

    I am writing a series of blogs on implementing DDD. I have detailed how to implement entities and vo’s. Have a look at them at http://stochastyk.blogspot.com/2008/05/series-on-domain-driven-design.html.

  • @Kaushik

    I’d say that’s pretty common. I redraw the aggregate lines a few times before it settles into something stable. I kept forgetting that child entities in an aggregate only have unique identity inside an aggregate. Once I defined these entities with this in mind, it eliminates quite a few aggregate boundary candidates.

    If you have one entity that seems to belong to two roots, it’s likely you have three roots in actuality.

  • Jimmy, This post is in Spanish now, thanks for let me repost it. http://mario-chavez.blogspot.com/2008/05/entidades-objetos-por-valor-agregados-y.html

  • Mark Holtman


    Thanks for a very concise explanation of these basic concepts. Your concrete examples helped solidify some of my thinking. I’m making my way through Evan’s DDD book at the moment and was struggling with what a Value Object is, ideally.

  • Hi,
    thank you for the very good explanation of these DDD basic concepts.
    I still disagree with the following statement:
    ‘Only Aggregate Roots can be obtained directly with database queries. Everything else must be done through traversal.’

    Navigation usually means exposing internal data (getters/setters) and leads to ‘Law of Demeter’ violation, and will make unit-testing more difficult
    (see design-style/’train wrecks’ http://www.martinfowler.com/articles/mocksArentStubs.html)

  • @Tudor-Andrei

    Do you have an example of this? Both Law of Demeter and how unit testing are made difficult?

  • Besides the above link MocksArentStubs I could suggest http://googletesting.blogspot.com/2008/07/breaking-law-of-demeter-is-like-looking.html.

    The point that if you have code depending on a navigation a.B.C.D then in the unit-test you’ll have to create/stub mock A & B & C & D. Either you go with slow integration tests with real domain-objects, or you go with object-mothers and (in both cases you’ll have to create real objects, probably through factories which might contain aspects/entities irrelevant to your test). Or you try to create mocks for those, but you still have to create a forest of mocks.

    Another point is what happens if you have navigation A.B but during the production you want to reverse its direction to B.A. Suddenly you’ll have to refactor all the code based on that navigation.

    I know that is 10000x more difficult, but keeping the navigation internal, in the entities, and using a very strict ‘Tell don’t Ask’ will be on a long run more efficient.javascript:WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions(“ctl00$ctl00$ctl00$bcr$bcr$bcr$ctl11$ctl02$ctl02$ctl02$btnSubmit”, “”, true, “CreateCommentForm”, “”, false, true))

  • kengkaj

    Thanks for your great article.

  • I have some problem with the “Only Aggregate Roots can be obtained directly with database queries”-Rule. Take the following Use-Case as an example. I have Orders and Order-Lines. Orders are the rootEntity of OrderLines. OrderLines have a product-type like “Toshiba Notebook N750″. Now I need to do some work with OrderLines of a special product-type. Therefore I need to pull them from the repository. If I would use the Order-Repository it would pull me out all Orders with at least one OrderLine of the desired type and of course all the other OrderLines of those orders. That won’t be acceptable from a performance point of view. How can I circumvent this ? Only lazyload the other OrderLines ?

  • @Chriz

    How is the information viewed? Who is viewing it? These questions lead me to what my boundaries are, not only for aggregates, but services and systems.

  • Chriz

    Normaly when working with orders, you have something like an order number. And in many cases you will access you order-lines only by an order. But imagine we need a list of orderlines of a special product. Something like “give me all orderlines of products from toshiba” to show them on the screen. Imagine each order could hold hundrets of orderlines. Accessing them through their orders would be impossible.

    • Paul Taylor

      I know this is a very old question, but I may have an answer. As Jimmy said, who is looking at this, for what purpose? It sounds to me like you have a report. The way I look at it, DDD is intended to ensure that your remain consistent and valid during a transaction. So you would use your DDD Aggregates when you are performing some action against the line items. When you are reporting on line items however, you don’t need to access this data through your model. See CQRS. It sounds to me like you have a reporting scenario, where you want to display a list of line items on screen based on some query parameters. You could achieve this by having a ReportingLineItem model for example, which contains all the properties required for your report display. If you then needed to perform some update on the line items, then I would imagine you would have some sort of button on screen to “edit line item”. This button would then use the line item Num and order ID to load up your aggregate, and you could then perform your actions against that aggregate. My terminology here is a bit sloppy as you would never have something as vague as “edit line item”. You would probably have some task based UI which allows you to “remove line item from order” or “change line item QTY” and these tasks would likely map to methods on your aggregate.

      • Chris Rush

        Hi, this is more of a question than a comment. Please don’t take it as a criticism in any way. I’m seeking clarification on a few topics.

        ReportingLineItem sounds like a ViewModel as you described it “contains all the properties required for your report display.” I think maybe I understand what you are getting at though. Please correct me if I’m wrong.

        It seems like OrderItem is still an entity, but a child entity of the Order aggregate. However, it’s possible for OrderItem to exist outside of Order in some cases (our system gives each OrderItem a unique identity that doesn’t rely on OrderItem at all. This allows us to move it from Order to Order without it’s unique ID changing, which may be referenced by other entities or value objects.)

        You are actually suggesting, I think, to create something like a ProductTypeOrderReport aggregate. This new aggregate would have the filtered line items as a child entity (collection). But what is the aggregate root of this object? Does an aggregate root have to be an entity that is stored in a database?

        On the topic of CQRS, I also have some concerns:

        I’ve done a ton of research on the topic, and I’m still not sure how CQRS solves anything that the Repository Pattern doesn’t. The only benefits seem to be that it separates commands and queries into single objects instead of grouping them under a single repository object (this part of the pattern is just CQS). While this could be a huge benefit if you need to distribute reads and writes, in most systems, this isn’t even a fleeting concern. CQRS seems to further dictate that you should do some type of Event Sourcing system and distributed computing, which again, isn’t needed in most systems. Yet, it’s still being pushed now as the “replacement” for the repository pattern.

        Yet, I’ve found that I still need the Repository pattern to abstract the DAL when using CQS. My repository pattern is just generic now, and does nothing more than abstract the DAL rather than house refined queries outside the scope of entity CRUD operations (for example, no specialized repositories with FindWithProductType() style methods). I’ve struggled, though, with the ability to unit test with CQRS. If a command is new’d in a method that I’m trying to unit test, and that command has DAL specific logic in it, then I’ve introduced hidden complexity, and no way to mock the command to not, for example, query a database.

        If the commands still rely on a Repository implementation, then I can mock the repository still. Furthermore, I’ve created a CQSFactory that allows me to do stuff like cqsFactory.Create(), and get injected with dependencies from my IoC container. So, this has solved some of the issues with unit testing CQRS, but I still don’t understand the argument that CQRS obsoletes the Repository pattern.

        I’ve read articles that Repository pattern is an anti-pattern, etc. Are they simply talking about specializing repositories? Are they excluding using a repository as a means to abstract access to the DAL?

        Thanks in advance. Hope to hear some good feedback.

  • Pingback: Cascade Save-Update in NHibernate and version column « FrankMao.com()

  • Pingback: Taking executable specs to the next level: Executable Documentation « KeithPS()

  • Pingback: Is RavenDB all it's cracked up to be? | techpour.com()

  • mewm

    7 years later and this article is still applicable and very helpful :)

  • eoin

    how do i pull agggregates from one large object iam getting back in an api call? i need to map the large json object into its aggregate and aggregate roots??

    • jbogard


      • eoin

        thought the question was relatively clear :)

      • eoin

        the answer is anticorruption layer.