The Anatomy of the Party Archetype

The Party archetype is the foundation for modeling business participants. Discover how separating identity, roles, and relationships creates a flexible domain model that grows with changing business needs.

The Anatomy of the Party Archetype

If you would like to see archetypes applied in practice, I maintain an open-source repository demonstrating archetypes implemented alongside Domain-Driven Design patterns: https://github.com/smalaca/archetypes


In our previous article, we discussed why tactical DDD building blocks sometimes aren't enough and how Archetypes provide the necessary blueprints for complex systems. Now, it's time to zoom in on the most fundamental archetype of all: the Party.

The Party archetype is the structural answer to "who" participates in your business. While many developers default to a User or Account entity, these concepts are often too narrow. The Party archetype provides a more resilient, scalable way to model participants.

What is the Party Archetype?

At its core, a Party is an identifiable entity - either a person or an organization - that has a relationship with your business.

When to use it:

  • When your system needs to interact with both individuals and legal entities.
  • When the same entity can play multiple roles (e.g., a person is both an employee and a customer).
  • When you need to track complex relationships between entities (e.g., who works for whom).

Pros:

  • Flexibility: Handles changing business roles without altering the core identity.
  • Consistency: Provides a unified way to handle addresses, identifiers, and contact points.
  • Scalability: New types of participants can be added with minimal impact on existing logic.

Cons:

  • Initial Complexity: More moving parts than a simple User table.
  • Abstraction Overhead: Requires developers to think in terms of roles rather than direct entity attributes.

The Starting Point: The Party

Every participant in the system starts as a Party. A Party is an abstraction that holds information common to everyone we deal with, regardless of whether they are a human or a company.

In a domain model, we often see this represented through common traits or base classes. For example, every Party has a way to be uniquely identified and a location where they can be reached.

By keeping identifiers (like SSNs or Tax IDs) and addresses at this level, we ensure that no matter what type of party we deal with, we have a consistent way to identify and locate them.

Specializing: Person and Organization

The next level of detail splits the Party into two concrete types: Person and Organization. This is where we capture the data unique to their nature.

Person represents a single human being. An Organization represents a legal or social entity, such as a corporation, a department, or a non-profit.

@ArchetypeParty.Party
@ArchetypeParty.Person
public class User {
    private final UserId userId;
    private final Login login;
    // ...
}

@ArchetypeParty.Party
@ArchetypeParty.Organization
public class Company {
    private final CompanyId companyId;
    private final List<CompanyRegisteredIdentifier> registeredIdentifiers;
    private final CompanyName primaryName;
    // ...
}

This separation prevents us from having "Organization Name" fields on a Person, or "Date of Birth" fields on a Company.

Behavioral Context: The Party Role

One of the biggest mistakes in modeling is attaching behavior directly to the Person or Organization. A person isn't just a "Buyer"; they play the role of a Buyer.

Party Role decouples the identity of the Party from the context in which they are acting.

In a well-structured model, the PartyRole refers back to the Party (often by ID) and adds the behavior specific to that role:

@ArchetypeParty.PartyRole
@ArchetypeParty.PartyRoleType
public class Buyer {
    private final PartyId partyId;
    private final BuyerId buyerId;
    private final TaxNumber taxNumber;
    // ...
}

This allows a single Person (Party) to be both a Student and a Trainer (Roles) simultaneously, without any conflict in the core data model.

Connecting the Dots: Party Relationship

Finally, we need to model how these parties and roles interact. A Party Relationship is a first-class citizen that connects two or more Party Roles.

For example, a "Representation" relationship connects a Representative (a Role played by a Person) with a Company (an Organization).

@ArchetypeParty.PartyRelationship
public class Representation {
    private final RepresentationId representationId;
    private final RepresentativeId representativeId;
    private final BusinessUnitId businessUnitId;
    // ...
}

By making the relationship an explicit object, we can store metadata about the connection itself, such as the start date of employment, the level of authority, or the specific business unit being represented.

Summary

The Party archetype is more than just a hierarchy; it's a flexible framework for modeling the social and legal fabric of a business.

  1. Party: The core identity.
  2. Person / Organization: The specialization of that identity.
  3. Party Role: The context-specific behavior.
  4. Party Relationship: The connection between roles.

In the next article, we'll see how to implement this without falling into the "Inheritance Trap" by using identity-based decoupling.