Preface
- Could this book be valuable for you?
- What are the 3 main goals of this book?
- Why I wrote this book
- Who should read this book?
- How to navigate this book
- Some final preliminary remarks
- Disclaimer about Terminology used in this book
- About the author
Part 1: The main DDD concepts from the bird’s eye view
- Design driven by the Domain Model
- A Model that builds upon the Ubiquitous Language
- A Single Model
- A “Rich” Model
- Knowledge Crunching: Model Analysis Sessions that include the Developers
- Continuous Learning
- Splitting the Enterprise Model on several Levels of Abstraction
- Strategic Design vs Tactical Design plus Application Layering
Part 2: Dissecting Strategic Design
- Making sense of the Domain- and Subdomain concepts
- What is a Domain?
- The Default Case: One Organization, One Domain
- What is a Subdomain?
- Domain vs Subdomain example 1: Insurance company
- Core (Sub-)Domain, Supporting Subdomain, Generic Subdomain
- Dissecting the concept of Bounded Contexts and the Context Map
- Bounded Context Identification Criteria
- What is a Context Map?
- Challenging the Bounded Context Criteria by Examples
- Bounded Context Design Example 1: A Company selling digital products
- Bounded Context Design Example 2: Transactions in the banking domain
- Bounded Context Design Example 3: Orders within the Subdomain “Securities Trading”
Part 3: Backend Application Architecture for Clean Bounded Contexts
- The Layered Architecture of purist DDD-compliant Applications
- The missing Technology-specific Invocation Layer
- Responsibilities of the Application (Service) Layer
- Introducing Ports & Adapters
- Ports & Adapters in a nutshell
- Aligning Ports & Adapters with DDD
- Why Ports & Adapters at all?
- Dissection: What exactly is the “Domain-Layer”?
- What is a DDD “Service” a.k.a. “Domain Service”?
- Challenging Domain Services using Evans’ FundsTransferService example
- Challenge: Shall Domain Entities be allowed to invoke services?
- Dissection: The Domain Layer and Isolation
- What is a DDD Repository?
- Challenge: Strict vs. “pragmatic” isolation: Unification of persistence- and domain model?
- Definition of “Clean Bounded Context”
Part 4: Dissecting Tactical Design
- What is a Domain Entity?
- What is a Value Object
- Dissecting Aggregate Design: Aiming for “Clean Aggregates”
- The classical Order and OrderItem Aggregate example
- Why is the aggregate design of such central importance?
- Aggregate Design Rules
- Practical Aggregate Design Guidance via the “Clean Aggregate Design Checklist”
- The “Clean Aggregate Design Checklist”
- Other general Domain Model Design Rules
- Design Rule “Make the implicit explicit”
- Design Rule “Prefer concrete over generic models in the Core Subdomain”
- Wrap a Collection of Value Objects into an expressive Wrapper type
- What is a DDD Factory?
Part 5: Challenging the Aggregate Consistency Boundary Rule
- Applicability of “Eventual Consistency” in cases of Multi-Aggregate Write Operations
- Why Clients may shy away from applying Eventual Consistency
- Introduction to the “New Customer submits his first Order” example
- Eventual Consistency Variation 1: Domain Event-based implementation with strict Aggregate Separation
- Structuring the flow of Domain Events and Transactions
- The Technical Infrastructure for using Domain Events
- Introducing the Outbox Pattern
- Introducing the Payload Model for Domain Events
- Technology Candidates for sending and receiving domain events
- Code Examples from the Webshop Backend Application
- Why do we also need some kind of Batch Application?
- Eventual Consistency Variation 2: Using a Business Process Engine (“BPE”)
- BPE Architecture considerations
- Variation 2.A: Embedded BPE
- Variation 2.B: Centralized BPE
- Example Architecture with 3 Bounded Contexts, BPE and Domain Events
- Eventual Consistency Variation 3: Violating the Consistency Boundary Rule
- Introducing the “Cross-Aggregate Application Service”
- Eventual Consistency Conclusion
- Is Eventual Consistency generally worth the effort?
- What about Event Sourcing and Event Replay?
- Which Eventual Consistency Variation is preferrable?
- The Bottom Line
- A brief Note about other Orchestration Techniques
- Challenging Strict Isolation with Concurrent Modification Scenarios
- Option 1: Partial Update
- Option 2: Full Entity Replacement via EntityManager.merge()
- Conclusion
Part 6: Tactical Design Example 2: The Football Association Management System (“FAMS”)
- Why you should work through this part
- A little context about the client
- Knowledge Crunching Session 1: The Foundations
- Starting off with an initial Big Picture of the Domain Model
- Challenge: How to keep domain models clean in the face of ternary associatons
- Challenge: Why LeagueDefinition and League are separate Aggregates
- Challenge: Clean Code vs Ubiquitous Language
- Challenge: How about letting Domain- and Persistence Aggregates deviate for Ternary Associations?
- Challenge: How about bypassing the Domain Layer for simple CRUD Use Cases?
- Revisiting the Ternary Association “Season-Team-Player”
- Challenge: How practical is Evans’ “One Model”-Paradigm?
- Challenge: Choosing the best approach for the 2nd Knowledge Crunching Session
- Model-driven Knowledge Crunching vs Event Storming vs Effective Use Cases
- Knowledge Crunching Session 2: Big Picture Event Storming
- Conclusion of the Big Picture Event Storming Session
- Knowledge Crunching Session 3: Deep-dive into the Player Lifecycle
- Challenge: Iteratively improving the Player Aggregate
- Revision 1 of the Player Domain Model
- Revision 2 of the Player Domain Model
- Designing a state diagram for the Player Entity
- Analyzing the Invariants for Application and Player
- Revision 4 of the Player Domain Model
- Revision 5 of the Player Domain Model or: Isn’t Transfer also a kind of Application?
- Revision 6 of the Player Domain Model: Explicit Application-Types
- Challenge: Should we replace the State Pattern in the Player Entity
- Revision 7 of the Player Aggregate Model: Splitting up the Player Entity
- Challenge: The impact of concurrent modification scenarios on the aggregate design
- Example Concurrent Modification Scenario for a Registration Application
- Challenge: Applying the Clean Aggregate Design Checklist
- Is RegistrationApplication an Aggregate Root Entity?
- Are the FollowupApplication Types Aggregate Root Entities?
- Aggregate Design Showcase for the Team Entity Cluster
Part 7: Writing “Clean Domain-driven Code”: Examples from the FAMS System
- The Basics: How to create Aggregate Instances in a clean and convenient way
- Example 1: Implementing the Use Case “Initiate Player Registration”
- The PlayerResource REST-Service
- The InitPlayerRegistrationApplicationService
- The creation of the transient Player domain object
- Example 2: Implementing the Use Case “Add SquadMember to Lineup”
- The AddNominatedPlayerToLineupApplicationService
- The AssertPlayerCanBeAddedToLineupDomainService
- Part 7-Conclusion about “Clean Domain-driven Code”
Part 8: Further Architectural Topics
- Communicating with other Bounded Contexts
- DDD with Third-Party- or Legacy Core Systems
- An architectural Variation: Spring Modulith + jMolecules