Domain Driven Design

From bibbleWiki
Jump to navigation Jump to search

Introduction

Love theory and try to stick to something where a pattern exists so I thought a page on this might not go a miss

Domain-Driven Design (DDD) Building Blocks

A consolidated reference for the core conceptual building blocks used in Domain-Driven Design. These patterns form the vocabulary of a rich domain model and guide how business logic is structured.

1. Value Object

Definition

A Value Object represents a concept in the domain that is defined entirely by its data.

Characteristics

Identity by value

Immutable

No lifecycle

Owned by an Entity

No identity key

Examples

Money

Address

DateRange

Coordinates

Notes

Use Value Objects to express meaning and enforce invariants.

2. Entity

Definition

An Entity represents something in the domain with a unique identity that persists over time.

Characteristics

Identity by ID

Mutable

Has a lifecycle

Can contain Value Objects

Examples

User

Order

Pizza

Notes

Entities model things that exist and change.

3. Aggregate

Definition

A cluster of Entities and Value Objects that form a consistency boundary.

Characteristics

Has a single Aggregate Root

Enforces invariants

Only the root is accessed from outside

Treated as a single unit

Examples

Order (root) with OrderLines

Cart (root) with CartItems

Notes

Aggregates define transactional boundaries.

4. Domain Service

Definition

A stateless operation that belongs to the domain but not to any specific Entity or Value Object.

Characteristics

Pure behaviour

No state

Encapsulates domain logic that does not fit elsewhere

Examples

PaymentProcessor

PricingCalculator

Notes

Use Domain Services sparingly and only when behaviour cannot live in an Entity or Value Object.

Explanation of Layer Placement

Domain Services live in the Domain Layer (Business Logic) because they encapsulate domain-specific behavior that does not naturally belong to any single Entity or Value Object. They focus purely on domain rules and operations without managing state or infrastructure concerns.

Why Not Application or Infrastructure Services?

Application Services coordinate workflows and manage transactions but contain little or no domain logic themselves. They live in the Application Layer.

Infrastructure Services provide technical capabilities like persistence, messaging, or external system integration and live in the Infrastructure Layer.

Example Clarifications

PaymentProcessor is a Domain Service because it encapsulates domain rules for processing payments, which involves domain logic beyond simple data storage or retrieval.

PricingCalculator is a Domain Service because it calculates prices based on business rules and discounts, which is domain behavior, not just application orchestration or infrastructure tasks.

5. Domain Event

Definition

A record of something meaningful that happened in the domain.

Characteristics

Immutable

Named in the past tense

Handled by domain or application logic

Examples

OrderPlaced

UserRegistered

Notes

Domain Events capture facts the system cares about.

6. Repository

Definition

An abstraction for retrieving and persisting Aggregates.

Characteristics

Works with Aggregate Roots

Hides persistence details

Returns domain objects

Examples

IOrderRepository

ICustomerRepository

Notes

Repositories provide a collection-like interface for Aggregates.

7. Factory

Definition

A pattern for creating complex domain objects or Aggregates.

Characteristics

Encapsulates creation logic

Ensures invariants are satisfied at creation time

Examples

OrderFactory

UserFactory

Notes

Use when creation requires more than simple construction.

8. Specification

Definition

A reusable, composable way to express business rules or filtering logic.

Characteristics

Encapsulates a predicate

Can be combined (AND, OR, NOT)

Often used for querying

Examples

OrdersPlacedInLast30Days

CustomersWithOverdueInvoices

Notes

Specifications help keep logic reusable and expressive.

Summary Table

Concept Identity Mutable Purpose Example
Value Object By value No Represent meaning Money Additional details can be added here.
Entity By ID Yes Represent things that exist Order Includes unique identity.
Aggregate Root ID Yes Consistency boundary Order + OrderLines Defines transactional boundaries.
Domain Service None No Behaviour without identity PricingCalculator Stateless operations.
Domain Event N/A No Record of something that happened OrderPlaced Immutable facts.
Repository N/A N/A Persistence abstraction IOrderRepository Collection-like interface.
Factory N/A N/A Controlled creation OrderFactory Encapsulates creation logic.
Specification N/A N/A Business rule expression OrdersPlacedInLast30Days Reusable predicates.

9. Invariants

Definition

Invariants are rules or conditions that always stay true and never change, no matter what happens in the system. They are like promises or guarantees that certain things will remain constant throughout the life of an object or process.

Explanation

Think of invariants as safety rules that keep your system reliable and consistent. They ensure that the system's state is always valid.

Examples

A bank account balance can never be negative.

An order must always have at least one order line.

A user’s email address must be unique in the system.

The total quantity of items in a shopping cart cannot be less than zero.

A product’s price must always be greater than zero.

Notes

Invariants help maintain correctness and prevent errors by enforcing essential business rules consistently.

10. Example Project Structure

Overview

This example project structure demonstrates a practical organization of a Domain-Driven Design system implemented using Clean Architecture principles. It separates concerns into layers and organizes code for clarity, maintainability, and scalability.

Project Structure Example

An example of project structure can be found own repos https://git.bibble.co.nz/bibble235/dvdrental_api_cs

Notes

The Api project contains presentation and interface concerns such as HTTP endpoints, middleware, filters, and API documentation (Swagger).

The Application project contains application logic including services, DTOs, validation, and request/response models. It orchestrates domain objects but contains minimal business logic.

The Domain project contains the core business model including entities, value objects, domain interfaces, and domain rules.

The Infrastructure project contains technical implementations such as persistence, caching, security, and external integrations.

The Shared project contains reusable utilities, extensions, enums, and configuration attributes shared across layers.

This structure aligns well with Clean Architecture principles by clearly separating concerns and dependencies between layers.=== Overview ===

Clean Architecture is a software design approach that organizes code into layers with clear responsibilities, promoting maintainability, scalability, and testability.

Layers in Clean Architecture

Domain Layer: Contains the business logic and domain model, including Entities, Value Objects, Aggregates, Domain Services, Domain Events, Specifications, and Factories.

Application Layer: Coordinates application workflows and use cases, orchestrating domain objects and managing transactions.

Infrastructure Layer: Handles technical concerns like data persistence, messaging, external APIs, and other system integrations.

Presentation Layer: Manages user interfaces and user interactions.

Converting Design to Implementation

When converting a Domain-Driven Design into a working system using Clean Architecture:

Start by modeling the domain layer with Entities, Value Objects, Aggregates, and Domain Services that encapsulate business rules.

Define Application Services to coordinate use cases and workflows without embedding business logic.

Implement Infrastructure Services to provide technical capabilities, keeping them separate from domain logic.

Use Dependency Inversion to ensure that the domain layer is independent of infrastructure and frameworks.

Why This Matters

This separation ensures that business rules remain pure and unaffected by external changes, making the system easier to maintain and evolve.

Example

A PricingCalculator Domain Service lives in the Domain Layer because it encapsulates business rules for price calculation.

An OrderApplicationService in the Application Layer coordinates placing an order by calling domain objects and managing transactions.

A PaymentGateway in the Infrastructure Layer handles communication with external payment providers.