Understanding Aggregates and Aggregate Roots in Domain-Driven Design
This article explains the concepts of aggregates and aggregate roots in DDD, describes how to design aggregates through event storming with a concrete insurance underwriting example, and outlines key design principles and the relationships among aggregates, entities, and value objects.
Meaning of Aggregate and Aggregate Root
Aggregate : An aggregate is a collection of entities and value objects that are grouped together to fulfill a specific business purpose, similar to how individuals form societies, clubs, or departments. In a domain model, entities and value objects are the individuals, while the aggregate ensures they work together consistently, serving as the basic unit for data modification and persistence, each backed by a repository.
Aggregate Root : An aggregate has a root entity and a contextual boundary that defines which entities and value objects belong inside it, while aggregates themselves remain loosely coupled. The aggregate root prevents data inconsistency caused by uncontrolled modifications across entities, avoiding the need for locking mechanisms that would increase complexity and reduce performance.
Analogously, the aggregate root is the leader of an organization. It is both an entity with its own attributes and behavior, and the manager of the aggregate, coordinating internal entities and value objects according to fixed business rules.
Externally, the aggregate root acts as the interface for the aggregate; other contexts interact with it via its ID, ensuring that external objects cannot directly access internal entities.
How to Design an Aggregate?
Domain‑Driven Design (DDD) typically uses event‑storming, which involves use‑case, scenario, and user‑journey analysis to list possible business actions and events, identify the domain objects that cause them, and then determine the aggregate root and its tightly related entities and value objects.
Below is an insurance underwriting scenario illustrating the steps:
Step 1 : Conduct event‑storming to list all entities and value objects involved in the underwriting process, such as the policy application, insured object, customer, insured person, etc.
Step 2 : Choose the root entities (aggregate roots) from the many entities, e.g., the policy application and the customer, based on criteria like independent lifecycle, globally unique ID, and ability to manage other objects.
Step 3 : According to single‑responsibility and high‑cohesion principles, gather all entities and value objects that are tightly coupled with the aggregate root to form the aggregate.
Step 4 : Within the aggregate, draw the reference and dependency model. For example, the policy holder and insured person data are obtained via the customer ID from the customer aggregate and stored as value objects in the policy aggregate, making them redundant but safe from external changes.
Step 5 : Group related aggregates into the same bounded context based on business semantics.
Design principles from the book *Implementing Domain‑Driven Design* include:
Model true invariants inside the consistency boundary; aggregates enforce business rules to maintain data consistency.
Design small aggregates to avoid complexity, reduce lock contention, and improve scalability.
Reference other aggregates only by their unique IDs, not by direct object references.
Use eventual consistency between aggregates; a transaction should modify at most one aggregate, with cross‑aggregate changes handled via domain events.
Implement cross‑aggregate service calls at the application layer, avoiding direct domain service calls or database joins across aggregates.
Relationship and Differences Between Aggregate, Aggregate Root, Entity, and Value Object
Aggregate : High cohesion, low coupling; serves as the smallest boundary for splitting micro‑services, though over‑splitting is discouraged.
Aggregate Root : An entity with a globally unique identifier and independent lifecycle; the sole entry point to the aggregate, coordinating internal entities and value objects.
Entity : Has an ID, mutable state, lifecycle managed by the aggregate root, usually persisted, and can reference other entities, the root, or value objects.
Value Object : No ID, immutable, defined solely by its attribute values, used to describe the state of an entity, and should preferably reference only other value objects.
Standing on the Shoulders of Giants
Geek Time – Ouxin DDD Practice Course
“Cricket in the Field” – My Journey with DDD
dax.net – DDD Practice
Source: https://www.cnblogs.com/Courage129/p/14861100.html
Technical Learning Group : Join the WeChat group by adding the author’s WeChat (QR code shown) for further discussion.
Architecture Digest
Focusing on Java backend development, covering application architecture from top-tier internet companies (high availability, high performance, high stability), big data, machine learning, Java architecture, and other popular fields.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.