Understanding the Difference Between Entities and Value Objects in Domain Modelling

When designing software using Domain-Driven Design (DDD), one of the first decisions you’ll make is whether a concept in your model should be an Entity or a Value Object.
This distinction is crucial — it shapes how you design, persist, and reason about your data.

Let’s break it down using examples from our ongoing project, GoProcure, an enterprise-grade procurement system we’re building on this #CodeTrip journey.


What Is an Entity?

An Entity is an object that:

  • Has a unique identity (e.g., an Id or unique identifier)

  • Can change over time. (Muatable)

  • Is distinguished by its identity, not its attributes

Even if two entities have the same data, they are not the same if their identities differ.

Example from GoProcure:

Vendor and PurchaseOrder are Entities.

  • A Vendor might change their company name or address, but it’s still the same vendor.

  • A PurchaseOrder might have items added or removed, but it remains the same order as long as the PO number (or ID) remains constant.

public class Vendor
{
   public Guid Id { get; private set; }

    public string Name { get; private set; }

    public string Email { get; private set; }

    public Address Address { get; private set; } // Value Object

}

Here, Vendor is an Entity because it has a unique Id and lifecycle.
However, the Address inside it is a Value Object — let’s talk about that next.


What Is a Value Object?

A Value Object:

  • Has no unique identity

  • Is defined only by its attributes

  • Is immutable — if something changes, you replace it entirely with a new instance

Two Value Objects are considered equal if all their property values are the same.

Example from GoProcure:

Address, Money, or DateRange can be modeled as Value Objects.

public record Address(
   string Street,
   string City,
   string State,
   string Country,
   string PostalCode
);

If a Vendor’s address changes, we don’t “edit” the Address; we assign a new one.
The old Address simply ceases to exist.

The same logic applies to Money. If you have Money(100, "USD"), it’s interchangeable with any other instance having the same amount and currency — it has no identity.


Address as a Value Object vs Address as an Entity

This is where many developers get confused.

✅ Address as a Value Object:
Use this when Address is only an attribute of another entity — for example, a Vendor’s address or a DeliveryLocation field in a Purchase Order.

Here, you don’t care about tracking the Address separately — you just need its data.

✅ Address as an Entity:
Make it an Entity when Address itself has identity or lifecycle — for example:

  • A logistics system where addresses are verified, reused, or updated by many users

  • A shared “AddressBook” where multiple Vendors or Customers link to the same address record

In that case, Address might look like this:

public class Address
{

   public Guid Id { get; private set; }

   public string Street { get; private set; }

   public string City { get; private set; }

   public string State { get; private set; }

   public string Country { get; private set; }

   public string PostalCode { get; private set; }

}


Key Differences at a Glance

Feature Entity Value Object
Identity Has a unique ID No ID — defined by values
Mutability Mutable (state can change) Immutable (replace when changed)
Equality Based on ID Based on all attributes
Lifecycle Tracked over time Created and destroyed as needed
Example (GoProcure) Vendor, PurchaseOrder, PurchaseRequest Address, Money, DateRange

Why This Matters

Getting this distinction right ensures:

  • Cleaner domain models

  • Simpler persistence logic

  • Reduced duplication

  • Better performance (since Value Objects can often be embedded or cached easily)

It also improves how your ORM (like Entity Framework or JPA) maps data.
In EF, for example, you can treat Value Objects as owned types, embedded within their parent entities — reducing the need for extra tables.


Summary

In DDD:

  • Model Entities when identity and lifecycle matter.

  • Model Value Objects when you just need a reusable, immutable description of something.

For GoProcure:

  • Vendor, Item, PurchaseOrder, and ApprovalEntities

  • Address, Money, and DateRangeValue Objects

In the next post, we’ll explore Aggregation vs Composition vs Association — what each means, when to use them, and how they impact database design and cascading behavior in Entity Framework and JPA.


Leave a Comment

Your email address will not be published. Required fields are marked *