39,99 €
inkl. MwSt.
Sofort per Download lieferbar
- Format: ePub
- Merkliste
- Auf die Merkliste
- Bewerten Bewerten
- Teilen
- Produkt teilen
- Produkterinnerung
- Produkterinnerung
Bitte loggen Sie sich zunächst in Ihr Kundenkonto ein oder registrieren Sie sich bei
bücher.de, um das eBook-Abo tolino select nutzen zu können.
Hier können Sie sich einloggen
Hier können Sie sich einloggen
Sie sind bereits eingeloggt. Klicken Sie auf 2. tolino select Abo, um fortzufahren.
Bitte loggen Sie sich zunächst in Ihr Kundenkonto ein oder registrieren Sie sich bei bücher.de, um das eBook-Abo tolino select nutzen zu können.
Methods for managing complex software construction following the practices, principles and patterns of Domain-Driven Design with code examples in C#
This book presents the philosophy of Domain-Driven Design (DDD) in a down-to-earth and practical manner for experienced developers building applications for complex domains. A focus is placed on the principles and practices of decomposing a complex problem space as well as the implementation patterns and best practices for shaping a maintainable solution space. You will learn how to build effective domain models through the use of tactical…mehr
- Geräte: eReader
- ohne Kopierschutz
- eBook Hilfe
- Größe: 11.64MB
- Upload möglich
Andere Kunden interessierten sich auch für
- Avinash C. KakDesigning with Objects (eBook, ePUB)74,99 €
- Adam FowlerNoSQL For Dummies (eBook, ePUB)23,99 €
- Chris NodderEvil by Design (eBook, ePUB)27,99 €
- Paul McFedriesJavaScript Essentials For Dummies (eBook, ePUB)10,99 €
- John C. ShovicPython Essentials For Dummies (eBook, ePUB)10,99 €
- Jack MoffittProfessional XMPP Programming with JavaScript and jQuery (eBook, ePUB)42,99 €
- Joe FawcettBeginning XML (eBook, ePUB)25,99 €
-
-
-
Methods for managing complex software construction following the practices, principles and patterns of Domain-Driven Design with code examples in C#
This book presents the philosophy of Domain-Driven Design (DDD) in a down-to-earth and practical manner for experienced developers building applications for complex domains. A focus is placed on the principles and practices of decomposing a complex problem space as well as the implementation patterns and best practices for shaping a maintainable solution space. You will learn how to build effective domain models through the use of tactical patterns and how to retain their integrity by applying the strategic patterns of DDD. Full end-to-end coding examples demonstrate techniques for integrating a decomposed and distributed solution space while coding best practices and patterns advise you on how to architect applications for maintenance and scale.
This book presents the philosophy of Domain-Driven Design (DDD) in a down-to-earth and practical manner for experienced developers building applications for complex domains. A focus is placed on the principles and practices of decomposing a complex problem space as well as the implementation patterns and best practices for shaping a maintainable solution space. You will learn how to build effective domain models through the use of tactical patterns and how to retain their integrity by applying the strategic patterns of DDD. Full end-to-end coding examples demonstrate techniques for integrating a decomposed and distributed solution space while coding best practices and patterns advise you on how to architect applications for maintenance and scale.
- Offers a thorough introduction to the philosophy of DDD for professional developers
- Includes masses of code and examples of concept in action that other books have only covered theoretically
- Covers the patterns of CQRS, Messaging, REST, Event Sourcing and Event-Driven Architectures
- Also ideal for Java developers who want to better understand the implementation of DDD
Produktdetails
- Produktdetails
- Verlag: John Wiley & Sons
- Erscheinungstermin: 20. April 2015
- Englisch
- ISBN-13: 9781118714690
- Artikelnr.: 56905684
- Verlag: John Wiley & Sons
- Erscheinungstermin: 20. April 2015
- Englisch
- ISBN-13: 9781118714690
- Artikelnr.: 56905684
Scott Millett is the Director of IT for Iglu.com, and has been working with .NET since version 1.0. He was awarded the ASP.NET MVP in 2010 and 2011, and is the author of Professional ASP.NET Design Patterns and Professional Enterprise .NET.
Nick Tune is a software developer delivering solutions to complex business problems using technology, collaboration, and Domain-Driven Design. He continually seeks improvement by working on ambitious products and with enthusiastic people.
Nick Tune is a software developer delivering solutions to complex business problems using technology, collaboration, and Domain-Driven Design. He continually seeks improvement by working on ambitious products and with enthusiastic people.
INTRODUCTION xxxv
PART I: THE PRINCIPLES AND PRACTICES OF DOMAIN‐DRIVEN DESIGN
CHAPTER 1: WHAT IS DOMAIN‐DRIVEN DESIGN? 3
The Challenges of Creating Software for Complex Problem Domains 4
Code Created Without a Common Language 4
A Lack of Organization 5
The Ball of Mud Pattern Stifles Development 5
A Lack of Focus on the Problem Domain 6
How the Patterns of Domain‐Driven Design Manage Complexity 6
The Strategic Patterns of DDD 6
Distilling the Problem Domain to Reveal What Is Important 7
Creating a Model to Solve Domain Problems 7
Using a Shared Language to Enable Modeling Collaboration 7
Isolate Models from Ambiguity and Corruption 8
Understanding the Relationships between Contexts 9
The Tactical Patterns of DDD 9
The Problem Space and the Solution Space 9
The Practices and Principles of Domain‐Driven Design 11
Focusing on the Core Domain 11
Learning through Collaboration 11
Creating Models through Exploration and Experimentation 11
Communication 11
Understanding the Applicability of a Model 12
Constantly Evolving the Model 12
Popular Misconceptions of Domain‐Driven Design 12
Tactical Patterns Are Key to DDD 12
DDD Is a Framework 13
DDD Is a Silver Bullet 13
The Salient Points 13
CHAPTER 2: DISTILLING THE PROBLEM DOMAIN 15
Knowledge Crunching and Collaboration 15
Reaching a Shared Understanding through a Shared Language 16
The Importance of Domain Knowledge 17
The Role of Business Analysts 17
An Ongoing Process 17
Gaining Domain Insight with Domain Experts 18
Domain Experts vs Stakeholders 18
Deeper Understanding for the Business 19
Engaging with Your Domain Experts 19
Patterns for Effective Knowledge Crunching 19
Focus on the Most Interesting Conversations 19
Start from the Use Cases 20
Ask Powerful Questions 20
Sketching 20
Class Responsibility Collaboration Cards 21
Defer the Naming of Concepts in Your Model 21
Behavior‐Driven Development 22
Rapid Prototyping 23
Look at Paper‐Based Systems 24
Look For Existing Models 24
Understanding Intent 24
Event Storming 25
Impact Mapping 25
Understanding the Business Model 27
Deliberate Discovery 28
Model Exploration Whirlpool 29
The Salient Points 29
CHAPTER 3: FOCUSING ON THE CORE DOMAIN 31
Why Decompose a Problem Domain? 31
How to Capture the Essence of the Problem 32
Look Beyond Requirements 32
Capture the Domain Vision for a Shared Understanding of What Is Core 32
How to Focus on the Core Problem 33
Distilling a Problem Domain 34
Core Domains 35
Treat Your Core Domain as a Product Rather than a Project 36
Generic Domains 37
Supporting Domains 37
How Subdomains Shape a Solution 37
Not All Parts of a System will be Well Designed 37
Focus on Clean Boundaries over Perfect Models 38
The Core Domain Doesn’t Always Have to Be Perfect the First Time 39
Build Subdomains for Replacement Rather than Reuse 39
What if You Have no Core Domain? 39
The Salient Points 40
CHAPTER 4: MODEL‐DRIVEN DESIGN 41
What Is a Domain Model? 42
The Domain versus the Domain Model 42
The Analysis Model 43
The Code Model 43
The Code Model Is the Primary Expression of the Domain Model 44
Model‐Driven Design 44
The Challenges with Upfront Design 44
Team Modeling 45
Using a Ubiquitous Language to Bind the Analysis to the Code Model 47
A Language Will Outlive Your Software 47
The Language of the Business 48
Translation between the Developers and the Business 48
Collaborating on a Ubiquitous Language 48
Carving Out a Language by Working with Concrete Examples 49
Teach Your Domain Experts to Focus on the Problem and Not Jump to a Solution 50
Best Practices for Shaping the Language 51
How to Create Effective Domain Models 52
Don’t Let the Truth Get in the Way of a Good Model 52
Model Only What Is Relevant 54
Domain Models Are Temporarily Useful 54
Be Explicit with Terminology 54
Limit Your Abstractions 54
Focus Your Code at the Right Level of Abstraction 55
Abstract Behavior Not Implementations 55
Implement the Model in Code Early and Often 56
Don’t Stop at the First Good Idea 56
When to Apply Model‐Driven Design 56
If It’s Not Worth the Effort Don’t Try and Model It 56
Focus on the Core Domain 57
The Salient Points 57
CHAPTER 5: DOMAIN MODEL IMPLEMENTATION PATTERNS 59
The Domain Layer 60
Domain Model Implementation Patterns 60
Domain Model 62
Transaction Script 65
Table Module 67
Active Record 67
Anemic Domain Model 67
Anemic Domain Model and Functional Programming 68
The Salient Points 71
CHAPTER 6: MAINTAINING THE INTEGRITY OF DOMAIN MODELS WITH BOUNDED CONTEXTS 73
The Challenges of a Single Model 74
A Model Can Grow in Complexity 74
Multiple Teams Working on a Single Model 74
Ambiguity in the Language of the Model 75
The Applicability of a Domain Concept 76
Integration with Legacy Code or Third Party Code 78
Your Domain Model Is not Your Enterprise Model 79
Use Bounded Contexts to Divide and Conquer a Large Model 79
Defining a Model’s Boundary 82
Define Boundaries around Language 82
Align to Business Capabilities 83
Create Contexts around Teams 83
Try to Retain Some Communication between Teams 84
Context Game 85
The Difference between a Subdomain and a Bounded Context 85
Implementing Bounded Contexts 85
The Salient Points 89
CHAPTER 7: CONTEXT MAPPING 91
A Reality Map 92
The Technical Reality 92
The Organizational Reality 93
Mapping a Relevant Reality 94
X Marks the Spot of the Core Domain 94
Recognising the Relationships between Bounded Contexts 95
Anticorruption Layer 95
Shared Kernel 96
Open Host Service 97
Separate Ways 97
Partnership 98
An Upstream/Downstream Relationship 98
Customer‐Supplier 99
Conformist 100
Communicating the Context Map 100
The Strategic Importance of Context Maps 101
Retaining Integrity 101
The Basis for a Plan of Attack 101
Understanding Ownership and Responsibility 101
Revealing Areas of Confusion in Business Work Flow 102
Identifying Nontechnical Obstacles 102
Encourages Good Communication 102
Helps On‐Board New Starters 102
The Salient Points 103
CHAPTER 8: APPLICATION ARCHITECTURE 105
Application Architecture 105
Separating the Concerns of Your Application 106
Abstraction from the Complexities of the Domain 106
A Layered Architecture 106
Dependency Inversion 107
The Domain Layer 107
The Application Service Layer 108
The Infrastructural Layers 108
Communication Across Layers 108
Testing in Isolation 109
Don t Share Data Schema between Bounded Contexts 109
Application Architectures versus Architectures for Bounded Contexts 111
Application Services 112
Application Logic versus Domain Logic 114
Defining and Exposing Capabilities 114
Business Use Case Coordination 115
Application Services Represent Use Cases, Not Create, Read, Update, and Delete 115
Domain Layer As an Implementation Detail 115
Domain Reporting 116
Read Models versus Transactional Models 116
Application Clients 117
The Salient Points 120
CHAPTER 9: COMMON PROBLEMS FOR TEAMS STARTING OUT WITH DOMAIN‐DRIVEN DESIGN 121
Overemphasizing the Importance of Tactical Patterns 122
Using the Same Architecture for All Bounded Contexts 122
Striving for Tactical Pattern Perfection 122
Mistaking the Building Blocks for the Value of DDD 123
Focusing on Code Rather Than the Principles of DDD 123
Missing the Real Value of DDD: Collaboration, Communication, and Context 124
Producing a Big Ball of Mud Due to Underestimating the Importance of Context 124
Causing Ambiguity and Misinterpretations by Failing to Create a UL 125
Designing Technical‐Focused Solutions Due to a Lack of Collaboration 125
Spending Too Much Time on What’s Not Important 126
Making Simple Problems Complex 126
Applying DDD Principles to a Trivial Domain with Little Business Expectation 126
Disregarding CRUD as an Antipattern 127
Using the Domain Model Pattern for Every Bounded Context 127
Ask Yourself: Is It Worth This Extra Complexity? 127
Underestimating the Cost of Applying DDD 127
Trying to Succeed Without a Motivated and Focused Team 128
Attempting Collaboration When a Domain Expert Is Not Behind the Project 128
Learning in a Noniterative Development Methodology 128
Applying DDD to Every Problem 129
Sacrificing Pragmatism for Needless Purity 129
Wasted Effort by Seeking Validation 129
Always Striving for Beautiful Code 130
DDD Is About Providing Value 130
The Salient Points 130
CHAPTER 10: APPLYING THE PRINCIPLES, PRACTICES, AND PATTERNS OF DDD 131
Selling DDD 132
Educating Your Team 132
Speaking to Your Business 132
Applying the Principles of DDD 133
Understand the Vision 133
Capture the Required Behaviors 134
Distilling the Problem Space 134
Focus on What Is Important 134
Understand the Reality of the Landscape 135
Modeling a Solution 135
All Problems Are Not Created Equal 136
Engaging with an Expert 136
Select a Behavior and Model Around a Concrete Scenario 137
Collaborate with the Domain Expert on the Most Interesting Parts 137
Evolve UL to Remove Ambiguity 138
Throw Away Your First Model, and Your Second 138
Implement the Model in Code 139
Creating a Domain Model 139
Keep the Solution Simple and Your Code Boring 139
Carve Out an Area of Safety 140
Integrate the Model Early and Often 140
Nontechnical Refactoring 140
Decompose Your Solution Space 140
Rinse and Repeat 141
Exploration and Experimentation 142
Challenge Your Assumptions 142
Modeling Is a Continuous Activity 142
There Are No Wrong Models 142
Supple Code Aids Discovery 143
Making the Implicit Explicit 143
Tackling Ambiguity 144
Give Things a Name 145
A Problem Solver First, A Technologist Second 146
Don’t Solve All the Problems 146
How Do I Know That I Am Doing It Right? 146
Good Is Good Enough 147
Practice, Practice, Practice 147
The Salient Points 147
PART II: STRATEGIC PATTERNS: COMMUNICATING BETWEEN BOUNDED CONTEXTS
CHAPTER 11: INTRODUCTION TO BOUNDED CONTEXT INTEGRATION 151
How to Integrate Bounded Contexts 152
Bounded Contexts Are Autonomous 153
The Challenges of Integrating Bounded Contexts at the Code Level 153
Multiple Bounded Contexts Exist within a Solution 153
Namespaces or Projects to Keep Bounded Contexts Separate 154
Integrating via the Database 155
Multiple Teams Working in a Single Codebase 156
Models Blur 156
Use Physical Boundaries to Enforce Clean Models 157
Integrating with Legacy Systems 158
Bubble Context 158
Autonomous Bubble Context 158
Exposing Legacy Systems as Services 160
Integrating Distributed Bounded Contexts 161
Integration Strategies for Distributed Bounded Contexts 161
Database Integration 162
Flat File Integration 163
RPC 164
Messaging 165
REST 165
The Challenges of DDD with Distributed Systems 165
The Problem with RPC 166
RPC Is Harder to Make Resilient 167
RPC Costs More to Scale 167
RPC Involves Tight Coupling 168
Distributed Transactions Hurt Scalability and Reliability 169
Bounded Contexts Don’t Have to Be Consistent with Each Other 169
Eventual Consistency 169
Event‐Driven Reactive DDD 170
Demonstrating the Resilience and Scalability of Reactive Solutions 171
Challenges and Trade‐Offs of Asynchronous Messaging 173
Is RPC Still Relevant? 173
SOA and Reactive DDD 174
View Your Bounded Contexts as SOA Services 175
Decompose Bounded Contexts into Business Components 175
Decompose Business Components into Components 176
Going Even Further with Micro Service Architecture 178
The Salient Points 180
CHAPTER 12: INTEGRATING VIA MESSAGING 181
Messaging Fundamentals 182
Message Bus 182
Reliable Messaging 184
Store‐and‐Forward 184
Commands and Events 185
Eventual Consistency 186
Building an E‐Commerce Application with NServiceBus 186
Designing the System 187
Domain‐Driven Design 187
Containers Diagrams 188
Evolutionary Architecture 191
Sending Commands from a Web Application 192
Creating a Web Application to Send Messages with NServiceBus 192
Sending Commands 197
Handling Commands and Publishing Events 200
Creating an NServiceBus Server to Handle Commands 200
Configuring the Solution for Testing and Debugging 201
Publishing Events 204
Subscribing to Events 206
Making External HTTP Calls Reliable with Messaging Gateways 208
Messaging Gateways Improve Fault Tolerance 208
Implementing a Messaging Gateway 209
Controlling Message Retries 212
Eventual Consistency in Practice 215
Dealing with Inconsistency 215
Rolling Forward into New States 215
Bounded Contexts Store All the Data They Need Locally 216
Storage Is Cheap—Keep a Local Copy 217
Common Data Duplication Concerns 223
Pulling It All Together in the UI 224
Business Components Need Their Own APIs 225
Be Wary of Server‐Side Orchestration 226
UI Composition with AJAX Data 226
UI Composition with AJAX HTML 226
Sharing Your APIs with the Outside World 227
Maintaining a Messaging Application 227
Message Versioning 228
Backward‐Compatible Message Versioning 228
Handling Versioning with NServiceBus’s Polymorphic Handlers 229
Monitoring and Scaling 233
Monitoring Errors 233
Monitoring SLAs 234
Scaling Out 235
Integrating a Bounded Context with Mass Transit 235
Messaging Bridge 236
Mass Transit 236
Installing and Configuring Mass Transit 236
Declaring Messages for Use by Mass Transit 238
Creating a Message Handler 239
Subscribing to Events 239
Linking the Systems with a Messaging Bridge 240
Publishing Events 242
Testing It Out 243
Where to Learn More about Mass Transit 243
The Salient Points 243
CHAPTER 13: INTEGRATING VIA HTTP WITH RPC AND REST 245
Why Prefer HTTP? 247
No Platform Coupling 247
Everyone Understands HTTP 247
Lots of Mature Tooling and Libraries 247
Dogfooding Your APIs 247
RPC 248
Implementing RPC over HTTP 248
SOAP 249
Plain XML or JSON: The Modern Approach to RPC 259
Choosing a Flavor of RPC 263
REST 264
Demystifying REST 264
Resources 264
Hypermedia 265
Statelessness 265
REST Fully Embraces HTTP 266
What REST Is Not 267
REST for Bounded Context Integration 268
Designing for REST 268
Building Event‐Driven REST Systems with ASP.NET Web API 273
Maintaining REST Applications 303
Versioning 303
Monitoring and Metrics 303
Drawbacks with REST for Bounded Context Integration 304
Less Fault Tolerance Out of the Box 304
Eventual Consistency 304
The Salient Points 305
PART III: TACTICAL PATTERNS: CREATING EFFECTIVE DOMAIN MODELS
CHAPTER 14: INTRODUCING THE DOMAIN MODELING BUILDING BLOCKS 309
Tactical Patterns 310
Patterns to Model Your Domain 310
Entities 310
Value Objects 314
Domain Services 317
Modules 318
Lifecycle Patterns 318
Aggregates 318
Factories 322
Repositories 323
Emerging Patterns 324
Domain Events 324
Event Sourcing 326
The Salient Points 327
CHAPTER 15: VALUE OBJECTS 329
When to Use a Value Object 330
Representing a Descriptive, Identity‐Less Concept 330
Enhancing Explicitness 331
Defining Characteristics 333
Identity‐Less 333
Attribute‐Based Equality 333
Behavior‐Rich 337
Cohesive 337
Immutable 337
Combinable 339
Self‐Validating 341
Testable 344
Common Modeling Patterns 345
Static Factory Methods 345
Micro Types (Also Known as Tiny Types) 347
Collection Aversion 349
Persistence 35
NoSQL 352
SQL 353
Flat Denormalization 353
Normalizing into Separate Tables 357
The Salient Points 359
CHAPTER 16: ENTITIES 36
Understanding Entities 362
Domain Concepts with Identity and Continuity 362
Context‐Dependent 363
Implementing Entities 363
Assigning Identifiers 363
Natural Keys 363
Arbitrarily Generated IDs 364
Datastore‐Generated IDs 368
Pushing Behavior into Value Objects and Domain Services 369
Validating and Enforcing Invariants 371
Focusing on Behavior, Not Data 374
Avoiding the “Model the Real‐World” Fallacy 377
Designing for Distribution 378
Common Entity Modeling Principles and Patterns 380
Implementing Validation and Invariants with Specifications 380
Avoid the State Pattern; Use Explicit Modeling 382
Avoiding Getters and Setters with the Memento Pattern 385
Favor Hidden‐Side‐Effect‐Free Functions 386
The Salient Points 388
CHAPTER 17: DOMAIN SERVICES 389
Understanding Domain Services 390
When to Use a Domain Service 390
Encapsulating Business Policies and Processes 390
Representing Contracts 394
Anatomy of a Domain Service 395
Avoiding Anemic Domain Models 395
Contrasting with Application Services 396
Utilizing Domain Services 397
In the Service Layer 397
In the Domain 398
Manually Wiring Up 399
Using Dependency Injection 400
Using a Service Locator 400
Applying Double Dispatch 401
Decoupling with Domain Events 402
Should Entities Even Know About Domain Services? 403
The Salient Points 403
CHAPTER 18: DOMAIN EVENTS 405
Essence of the Domain Events Pattern 406
Important Domain Occurrences That Have Already Happened 406
Reacting to Events 407
Optional Asynchrony 407
Internal vs External Events 408
Event Handling Actions 409
Invoke Domain Logic 409
Invoke Application Logic 410
Domain Events’ Implementation Patterns 410
Use the .Net Framework’s Events Model 410
Use an In‐Memory Bus 412
Udi Dahan’s Static DomainEvents Class 415
Handling Threading Issues 417
Avoid a Static Class by Using Method Injection 418
Return Domain Events 419
Use an IoC Container as an Event Dispatcher 421
Testing Domain Events 422
Unit Testing 422
Application Service Layer Testing 424
The Salient Points 425
CHAPTER 19: AGGREGATES 427
Managing Complex Object Graphs 428
Favoring a Single Traversal Direction 428
Qualifying Associations 430
Preferring IDs Over Object References 431
Aggregates 434
Design Around Domain Invariants 435
Higher Level of Domain Abstraction 435
Consistency Boundaries 435
Transactional Consistency Internally 436
Eventual Consistency Externally 439
Special Cases 440
Favor Smaller Aggregates 441
Large Aggregates Can Degrade Performance 441
Large Aggregates Are More Susceptible to Concurrency Conflicts 442
Large Aggregates May Not Scale Well 442
Defining Aggregate Boundaries 442
eBidder: The Online Auction Case Study 443
Aligning with Invariants 444
Aligning with Transactions and Consistency 446
Ignoring User Interface Influences 448
Avoiding Dumb Collections and Containers 448
Don’t Focus on HAS‐A Relationships 449
Refactoring to Aggregates 449
Satisfying Business Use Cases—Not Real Life 449
Implementing Aggregates 450
Selecting an Aggregate Root 450
Exposing Behavioral Interfaces 452
Protecting Internal State 453
Allowing Only Roots to Have Global Identity 454
Referencing Other Aggregates 454
Nothing Outside An Aggregate’s Boundary May Hold a Reference to Anything Inside 455
The Aggregate Root Can Hand Out Transient References to the Internal Domain Objects 456
Objects within the Aggregate Can Hold References to Other Aggregate Roots 456
Implementing Persistence 458
Access to Domain Objects for Reading Can Be at the Database Level 460
A Delete Operation Must Remove Everything within the Aggregate Boundary at Once 461
Avoiding Lazy Loading 461
Implementing Transactional Consistency 462
Implementing Eventual Consistency 463
Rules That Span Multiple Aggregates 463
Asynchronous Eventual Consistency 464
Implementing Concurrency 465
The Salient Points 468
CHAPTER 20: FACTORIES 469
The Role of a Factory 469
Separating Use from Construction 470
Encapsulating Internals 470
Hiding Decisions on Creation Type 472
Factory Methods on Aggregates 474
Factories for Reconstitution 475
Use Factories Pragmatically 477
The Salient Points 477
CHAPTER 21: REPOSITORIES 479
Repositories 479
A Misunderstood Pattern 481
Is the Repository an Antipattern? 481
The Difference between a Domain Model and a Persistence Model 482
The Generic Repository 483
Aggregate Persistence Strategies 486
Using a Persistence Framework That Can Map the Domain Model to the Data Model without Compromise 486
Using a Persistence Framework That Cannot Map the Domain Model Directly without Compromise 487
Public Getters and Setters 487
Using the Memento Pattern 488
Event Streams 49
Be Pragmatic 491
A Repository Is an Explicit Contract 492
Transaction Management and Units of Work 493
To Save or Not To Save 497
Persistence Frameworks That Track Domain Object Changes 497
Having to Explicitly Save Changes to Aggregates 498
The Repository as an Anticorruption Layer 499
Other Responsibilities of a Repository 500
Entity ID Generation 500
Collection Summaries 502
Concurrency 503
Audit Trails 506
Repository Antipatterns 506
Antipatterns: Don’t Support Ad Hoc Queries 506
Antipatterns: Lazy Loading Is Design Smell 507
Antipatterns: Don’t Use Repositories for Reporting Needs 507
Repository Implementations 508
Persistence Framework Can Map Domain Model to Data Model without Compromise 509
NHibernate Example 509
RavenDB Example 543
Persistence Framework Cannot Map Domain Model Directly without Compromise 557
Entity Framework Example 558
Micro ORM Example 577
The Salient Points 593
CHAPTER 22: EVENT SOURCING 595
The Limitations of Storing State as a Snapshot 596
Gaining Competitive Advantage by Storing State as a Stream of Events 597
Temporal Queries 597
Projections 599
Snapshots 599
Event‐Sourced Aggregates 600
Structuring 600
Adding Event‐Sourcing Capabilities 601
Exposing Expressive Domain‐Focused APIs 602
Adding Snapshot Support 604
Persisting and Rehydrating 605
Creating an Event-Sourcing Repository 605
Adding Snapshot Persistence and Reloading 607
Handling Concurrency 609
Testing 610
Building an Event Store 611
Designing a Storage Format 612
Creating Event Streams 614
Appending to Event Streams 614
Querying Event Streams 615
Adding Snapshot Support 616
Managing Concurrency 618
A SQL Server‐Based Event Store 621
Choosing a Schema 621
Creating a Stream 622
Saving Events 623
Loading Events from a Stream 624
Snapshots 625
Is Building Your Own Event Store a Good Idea? 627
Using the Purpose‐Built Event Store 627
Installing Greg Young’s Event Store 628
Using the C# Client Library 627
Running Temporal Queries 632
Querying a Single Stream 632
Querying Multiple Streams 634
Creating Projections 635
CQRS with Event Sourcing 637
Using Projections to Create View Caches 638
CQRS and Event Sourcing Synergy 638
Event Streams as Queues 639
No Two‐Phase Commits 639
Recapping the Benefits of Event Sourcing 639
Competitive Business Advantage 639
Expressive Behavior‐Focused Aggregates 639
Simplified Persistence 640
Superior Debugging 640
Weighing the Costs of Event Sourcing 640
Versioning 640
New Concepts to Learn and Skills to Hone 640
New Technologies to Learn and Master 641
Greater Data Storage Requirements 641
Additional Learning Resources 641
The Salient Points 641
PART IV: DESIGN PATTERNS FOR EFFECTIVE APPLICATIONS
CHAPTER 23: ARCHITECTING APPLICATION USER INTERFACES 645
Design Considerations 646
Owned UIs versus Composed UIs 646
Autonomous 646
Authoritative 647
Some Help Deciding 648
HTML APIs versus Data APIs 649
Client versus Server‐Side Aggregation/Coordination 649
Example 1: An HTML API‐Based, Server‐Side UI for Nondistributed Bounded Contexts 651
Example 2: A Data API‐Based, Client‐Side UI for Distributed Bounded Contexts 658
The Salient Points 667
CHAPTER 24: CQRS: AN ARCHITECTURE OF A BOUNDED CONTEXT 669
The Challenges of Maintaining a Single Model for Two Contexts 670
A Better Architecture for Complex Bounded Contexts 670
The Command Side: Business Tasks 672
Explicitly Modeling Intent 672
A Model Free from Presentational Distractions 674
Handling a Business Request 675
The Query Side: Domain Reporting 676
Reports Mapped Directly to the Data Model 676
Materialized Views Built from Domain Events 678
The Misconceptions of CQRS 679
CQRS Is Hard 679
CQRS Is Eventually Consistent 679
Your Models Need to Be Event Sourced 680
Commands Should Be Asynchronous 680
CQRS Only Works with Messaging Systems 680
You Need to Use Domain Events with CQRS 680
Patterns to Enable Your Application to Scale 680
Scaling the Read Side: An Eventually Consistent Read Model 681
The Impact to the User Experience 682
Use the Read Model to Consolidate Many Bounded Contexts 682
Using a Reporting Database or a Caching Layer 682
Scaling the Write Side: Using Asynchronous Commands 683
Command Validation 683
Impact to the User Experience 684
Scaling It All 684
The Salient Points 685
CHAPTER 25: COMMANDS: APPLICATION SERVICE PATTERNS FOR PROCESSING BUSINESS USE CASES 687
Differentiating Application Logic and Domain Logic 689
Application Logic 689
Infrastructural Concerns 690
Coordinating Full Business Use Cases 698
Application Services and Framework Integration 698
Domain Logic from an Application Service’s Perspective 700
Application Service Patterns 700
Command Processor 701
Publish/Subscribe 704
Request/Reply Pattern 706
async/await 708
Testing Application Services 709
Use Domain Terminology 709
Test as Much Functionality as Possible 710
The Salient Points 712
CHAPTER 26: QUERIES: DOMAIN REPORTING 713
Domain Reporting within a Bounded Context 714
Deriving Reports from Domain Objects 714
Using Simple Mappings 714
Using the Mediator Pattern 718
Going Directly to the Datastore 720
Querying a Datastore 721
Reading Denormalized View Caches 724
Building Projections from Event Streams 726
Setting Up ES for Projections 727
Creating Reporting Projections 728
Counting the Number of Events in a Stream 729
Creating As Many Streams As Required 729
Building a Report from Streams and Projections 730
Domain Reporting Across Bounded Contexts 733
Composed UI 733
Separate Reporting Context 734
The Salient Points 736
INDEX 737
PART I: THE PRINCIPLES AND PRACTICES OF DOMAIN‐DRIVEN DESIGN
CHAPTER 1: WHAT IS DOMAIN‐DRIVEN DESIGN? 3
The Challenges of Creating Software for Complex Problem Domains 4
Code Created Without a Common Language 4
A Lack of Organization 5
The Ball of Mud Pattern Stifles Development 5
A Lack of Focus on the Problem Domain 6
How the Patterns of Domain‐Driven Design Manage Complexity 6
The Strategic Patterns of DDD 6
Distilling the Problem Domain to Reveal What Is Important 7
Creating a Model to Solve Domain Problems 7
Using a Shared Language to Enable Modeling Collaboration 7
Isolate Models from Ambiguity and Corruption 8
Understanding the Relationships between Contexts 9
The Tactical Patterns of DDD 9
The Problem Space and the Solution Space 9
The Practices and Principles of Domain‐Driven Design 11
Focusing on the Core Domain 11
Learning through Collaboration 11
Creating Models through Exploration and Experimentation 11
Communication 11
Understanding the Applicability of a Model 12
Constantly Evolving the Model 12
Popular Misconceptions of Domain‐Driven Design 12
Tactical Patterns Are Key to DDD 12
DDD Is a Framework 13
DDD Is a Silver Bullet 13
The Salient Points 13
CHAPTER 2: DISTILLING THE PROBLEM DOMAIN 15
Knowledge Crunching and Collaboration 15
Reaching a Shared Understanding through a Shared Language 16
The Importance of Domain Knowledge 17
The Role of Business Analysts 17
An Ongoing Process 17
Gaining Domain Insight with Domain Experts 18
Domain Experts vs Stakeholders 18
Deeper Understanding for the Business 19
Engaging with Your Domain Experts 19
Patterns for Effective Knowledge Crunching 19
Focus on the Most Interesting Conversations 19
Start from the Use Cases 20
Ask Powerful Questions 20
Sketching 20
Class Responsibility Collaboration Cards 21
Defer the Naming of Concepts in Your Model 21
Behavior‐Driven Development 22
Rapid Prototyping 23
Look at Paper‐Based Systems 24
Look For Existing Models 24
Understanding Intent 24
Event Storming 25
Impact Mapping 25
Understanding the Business Model 27
Deliberate Discovery 28
Model Exploration Whirlpool 29
The Salient Points 29
CHAPTER 3: FOCUSING ON THE CORE DOMAIN 31
Why Decompose a Problem Domain? 31
How to Capture the Essence of the Problem 32
Look Beyond Requirements 32
Capture the Domain Vision for a Shared Understanding of What Is Core 32
How to Focus on the Core Problem 33
Distilling a Problem Domain 34
Core Domains 35
Treat Your Core Domain as a Product Rather than a Project 36
Generic Domains 37
Supporting Domains 37
How Subdomains Shape a Solution 37
Not All Parts of a System will be Well Designed 37
Focus on Clean Boundaries over Perfect Models 38
The Core Domain Doesn’t Always Have to Be Perfect the First Time 39
Build Subdomains for Replacement Rather than Reuse 39
What if You Have no Core Domain? 39
The Salient Points 40
CHAPTER 4: MODEL‐DRIVEN DESIGN 41
What Is a Domain Model? 42
The Domain versus the Domain Model 42
The Analysis Model 43
The Code Model 43
The Code Model Is the Primary Expression of the Domain Model 44
Model‐Driven Design 44
The Challenges with Upfront Design 44
Team Modeling 45
Using a Ubiquitous Language to Bind the Analysis to the Code Model 47
A Language Will Outlive Your Software 47
The Language of the Business 48
Translation between the Developers and the Business 48
Collaborating on a Ubiquitous Language 48
Carving Out a Language by Working with Concrete Examples 49
Teach Your Domain Experts to Focus on the Problem and Not Jump to a Solution 50
Best Practices for Shaping the Language 51
How to Create Effective Domain Models 52
Don’t Let the Truth Get in the Way of a Good Model 52
Model Only What Is Relevant 54
Domain Models Are Temporarily Useful 54
Be Explicit with Terminology 54
Limit Your Abstractions 54
Focus Your Code at the Right Level of Abstraction 55
Abstract Behavior Not Implementations 55
Implement the Model in Code Early and Often 56
Don’t Stop at the First Good Idea 56
When to Apply Model‐Driven Design 56
If It’s Not Worth the Effort Don’t Try and Model It 56
Focus on the Core Domain 57
The Salient Points 57
CHAPTER 5: DOMAIN MODEL IMPLEMENTATION PATTERNS 59
The Domain Layer 60
Domain Model Implementation Patterns 60
Domain Model 62
Transaction Script 65
Table Module 67
Active Record 67
Anemic Domain Model 67
Anemic Domain Model and Functional Programming 68
The Salient Points 71
CHAPTER 6: MAINTAINING THE INTEGRITY OF DOMAIN MODELS WITH BOUNDED CONTEXTS 73
The Challenges of a Single Model 74
A Model Can Grow in Complexity 74
Multiple Teams Working on a Single Model 74
Ambiguity in the Language of the Model 75
The Applicability of a Domain Concept 76
Integration with Legacy Code or Third Party Code 78
Your Domain Model Is not Your Enterprise Model 79
Use Bounded Contexts to Divide and Conquer a Large Model 79
Defining a Model’s Boundary 82
Define Boundaries around Language 82
Align to Business Capabilities 83
Create Contexts around Teams 83
Try to Retain Some Communication between Teams 84
Context Game 85
The Difference between a Subdomain and a Bounded Context 85
Implementing Bounded Contexts 85
The Salient Points 89
CHAPTER 7: CONTEXT MAPPING 91
A Reality Map 92
The Technical Reality 92
The Organizational Reality 93
Mapping a Relevant Reality 94
X Marks the Spot of the Core Domain 94
Recognising the Relationships between Bounded Contexts 95
Anticorruption Layer 95
Shared Kernel 96
Open Host Service 97
Separate Ways 97
Partnership 98
An Upstream/Downstream Relationship 98
Customer‐Supplier 99
Conformist 100
Communicating the Context Map 100
The Strategic Importance of Context Maps 101
Retaining Integrity 101
The Basis for a Plan of Attack 101
Understanding Ownership and Responsibility 101
Revealing Areas of Confusion in Business Work Flow 102
Identifying Nontechnical Obstacles 102
Encourages Good Communication 102
Helps On‐Board New Starters 102
The Salient Points 103
CHAPTER 8: APPLICATION ARCHITECTURE 105
Application Architecture 105
Separating the Concerns of Your Application 106
Abstraction from the Complexities of the Domain 106
A Layered Architecture 106
Dependency Inversion 107
The Domain Layer 107
The Application Service Layer 108
The Infrastructural Layers 108
Communication Across Layers 108
Testing in Isolation 109
Don t Share Data Schema between Bounded Contexts 109
Application Architectures versus Architectures for Bounded Contexts 111
Application Services 112
Application Logic versus Domain Logic 114
Defining and Exposing Capabilities 114
Business Use Case Coordination 115
Application Services Represent Use Cases, Not Create, Read, Update, and Delete 115
Domain Layer As an Implementation Detail 115
Domain Reporting 116
Read Models versus Transactional Models 116
Application Clients 117
The Salient Points 120
CHAPTER 9: COMMON PROBLEMS FOR TEAMS STARTING OUT WITH DOMAIN‐DRIVEN DESIGN 121
Overemphasizing the Importance of Tactical Patterns 122
Using the Same Architecture for All Bounded Contexts 122
Striving for Tactical Pattern Perfection 122
Mistaking the Building Blocks for the Value of DDD 123
Focusing on Code Rather Than the Principles of DDD 123
Missing the Real Value of DDD: Collaboration, Communication, and Context 124
Producing a Big Ball of Mud Due to Underestimating the Importance of Context 124
Causing Ambiguity and Misinterpretations by Failing to Create a UL 125
Designing Technical‐Focused Solutions Due to a Lack of Collaboration 125
Spending Too Much Time on What’s Not Important 126
Making Simple Problems Complex 126
Applying DDD Principles to a Trivial Domain with Little Business Expectation 126
Disregarding CRUD as an Antipattern 127
Using the Domain Model Pattern for Every Bounded Context 127
Ask Yourself: Is It Worth This Extra Complexity? 127
Underestimating the Cost of Applying DDD 127
Trying to Succeed Without a Motivated and Focused Team 128
Attempting Collaboration When a Domain Expert Is Not Behind the Project 128
Learning in a Noniterative Development Methodology 128
Applying DDD to Every Problem 129
Sacrificing Pragmatism for Needless Purity 129
Wasted Effort by Seeking Validation 129
Always Striving for Beautiful Code 130
DDD Is About Providing Value 130
The Salient Points 130
CHAPTER 10: APPLYING THE PRINCIPLES, PRACTICES, AND PATTERNS OF DDD 131
Selling DDD 132
Educating Your Team 132
Speaking to Your Business 132
Applying the Principles of DDD 133
Understand the Vision 133
Capture the Required Behaviors 134
Distilling the Problem Space 134
Focus on What Is Important 134
Understand the Reality of the Landscape 135
Modeling a Solution 135
All Problems Are Not Created Equal 136
Engaging with an Expert 136
Select a Behavior and Model Around a Concrete Scenario 137
Collaborate with the Domain Expert on the Most Interesting Parts 137
Evolve UL to Remove Ambiguity 138
Throw Away Your First Model, and Your Second 138
Implement the Model in Code 139
Creating a Domain Model 139
Keep the Solution Simple and Your Code Boring 139
Carve Out an Area of Safety 140
Integrate the Model Early and Often 140
Nontechnical Refactoring 140
Decompose Your Solution Space 140
Rinse and Repeat 141
Exploration and Experimentation 142
Challenge Your Assumptions 142
Modeling Is a Continuous Activity 142
There Are No Wrong Models 142
Supple Code Aids Discovery 143
Making the Implicit Explicit 143
Tackling Ambiguity 144
Give Things a Name 145
A Problem Solver First, A Technologist Second 146
Don’t Solve All the Problems 146
How Do I Know That I Am Doing It Right? 146
Good Is Good Enough 147
Practice, Practice, Practice 147
The Salient Points 147
PART II: STRATEGIC PATTERNS: COMMUNICATING BETWEEN BOUNDED CONTEXTS
CHAPTER 11: INTRODUCTION TO BOUNDED CONTEXT INTEGRATION 151
How to Integrate Bounded Contexts 152
Bounded Contexts Are Autonomous 153
The Challenges of Integrating Bounded Contexts at the Code Level 153
Multiple Bounded Contexts Exist within a Solution 153
Namespaces or Projects to Keep Bounded Contexts Separate 154
Integrating via the Database 155
Multiple Teams Working in a Single Codebase 156
Models Blur 156
Use Physical Boundaries to Enforce Clean Models 157
Integrating with Legacy Systems 158
Bubble Context 158
Autonomous Bubble Context 158
Exposing Legacy Systems as Services 160
Integrating Distributed Bounded Contexts 161
Integration Strategies for Distributed Bounded Contexts 161
Database Integration 162
Flat File Integration 163
RPC 164
Messaging 165
REST 165
The Challenges of DDD with Distributed Systems 165
The Problem with RPC 166
RPC Is Harder to Make Resilient 167
RPC Costs More to Scale 167
RPC Involves Tight Coupling 168
Distributed Transactions Hurt Scalability and Reliability 169
Bounded Contexts Don’t Have to Be Consistent with Each Other 169
Eventual Consistency 169
Event‐Driven Reactive DDD 170
Demonstrating the Resilience and Scalability of Reactive Solutions 171
Challenges and Trade‐Offs of Asynchronous Messaging 173
Is RPC Still Relevant? 173
SOA and Reactive DDD 174
View Your Bounded Contexts as SOA Services 175
Decompose Bounded Contexts into Business Components 175
Decompose Business Components into Components 176
Going Even Further with Micro Service Architecture 178
The Salient Points 180
CHAPTER 12: INTEGRATING VIA MESSAGING 181
Messaging Fundamentals 182
Message Bus 182
Reliable Messaging 184
Store‐and‐Forward 184
Commands and Events 185
Eventual Consistency 186
Building an E‐Commerce Application with NServiceBus 186
Designing the System 187
Domain‐Driven Design 187
Containers Diagrams 188
Evolutionary Architecture 191
Sending Commands from a Web Application 192
Creating a Web Application to Send Messages with NServiceBus 192
Sending Commands 197
Handling Commands and Publishing Events 200
Creating an NServiceBus Server to Handle Commands 200
Configuring the Solution for Testing and Debugging 201
Publishing Events 204
Subscribing to Events 206
Making External HTTP Calls Reliable with Messaging Gateways 208
Messaging Gateways Improve Fault Tolerance 208
Implementing a Messaging Gateway 209
Controlling Message Retries 212
Eventual Consistency in Practice 215
Dealing with Inconsistency 215
Rolling Forward into New States 215
Bounded Contexts Store All the Data They Need Locally 216
Storage Is Cheap—Keep a Local Copy 217
Common Data Duplication Concerns 223
Pulling It All Together in the UI 224
Business Components Need Their Own APIs 225
Be Wary of Server‐Side Orchestration 226
UI Composition with AJAX Data 226
UI Composition with AJAX HTML 226
Sharing Your APIs with the Outside World 227
Maintaining a Messaging Application 227
Message Versioning 228
Backward‐Compatible Message Versioning 228
Handling Versioning with NServiceBus’s Polymorphic Handlers 229
Monitoring and Scaling 233
Monitoring Errors 233
Monitoring SLAs 234
Scaling Out 235
Integrating a Bounded Context with Mass Transit 235
Messaging Bridge 236
Mass Transit 236
Installing and Configuring Mass Transit 236
Declaring Messages for Use by Mass Transit 238
Creating a Message Handler 239
Subscribing to Events 239
Linking the Systems with a Messaging Bridge 240
Publishing Events 242
Testing It Out 243
Where to Learn More about Mass Transit 243
The Salient Points 243
CHAPTER 13: INTEGRATING VIA HTTP WITH RPC AND REST 245
Why Prefer HTTP? 247
No Platform Coupling 247
Everyone Understands HTTP 247
Lots of Mature Tooling and Libraries 247
Dogfooding Your APIs 247
RPC 248
Implementing RPC over HTTP 248
SOAP 249
Plain XML or JSON: The Modern Approach to RPC 259
Choosing a Flavor of RPC 263
REST 264
Demystifying REST 264
Resources 264
Hypermedia 265
Statelessness 265
REST Fully Embraces HTTP 266
What REST Is Not 267
REST for Bounded Context Integration 268
Designing for REST 268
Building Event‐Driven REST Systems with ASP.NET Web API 273
Maintaining REST Applications 303
Versioning 303
Monitoring and Metrics 303
Drawbacks with REST for Bounded Context Integration 304
Less Fault Tolerance Out of the Box 304
Eventual Consistency 304
The Salient Points 305
PART III: TACTICAL PATTERNS: CREATING EFFECTIVE DOMAIN MODELS
CHAPTER 14: INTRODUCING THE DOMAIN MODELING BUILDING BLOCKS 309
Tactical Patterns 310
Patterns to Model Your Domain 310
Entities 310
Value Objects 314
Domain Services 317
Modules 318
Lifecycle Patterns 318
Aggregates 318
Factories 322
Repositories 323
Emerging Patterns 324
Domain Events 324
Event Sourcing 326
The Salient Points 327
CHAPTER 15: VALUE OBJECTS 329
When to Use a Value Object 330
Representing a Descriptive, Identity‐Less Concept 330
Enhancing Explicitness 331
Defining Characteristics 333
Identity‐Less 333
Attribute‐Based Equality 333
Behavior‐Rich 337
Cohesive 337
Immutable 337
Combinable 339
Self‐Validating 341
Testable 344
Common Modeling Patterns 345
Static Factory Methods 345
Micro Types (Also Known as Tiny Types) 347
Collection Aversion 349
Persistence 35
NoSQL 352
SQL 353
Flat Denormalization 353
Normalizing into Separate Tables 357
The Salient Points 359
CHAPTER 16: ENTITIES 36
Understanding Entities 362
Domain Concepts with Identity and Continuity 362
Context‐Dependent 363
Implementing Entities 363
Assigning Identifiers 363
Natural Keys 363
Arbitrarily Generated IDs 364
Datastore‐Generated IDs 368
Pushing Behavior into Value Objects and Domain Services 369
Validating and Enforcing Invariants 371
Focusing on Behavior, Not Data 374
Avoiding the “Model the Real‐World” Fallacy 377
Designing for Distribution 378
Common Entity Modeling Principles and Patterns 380
Implementing Validation and Invariants with Specifications 380
Avoid the State Pattern; Use Explicit Modeling 382
Avoiding Getters and Setters with the Memento Pattern 385
Favor Hidden‐Side‐Effect‐Free Functions 386
The Salient Points 388
CHAPTER 17: DOMAIN SERVICES 389
Understanding Domain Services 390
When to Use a Domain Service 390
Encapsulating Business Policies and Processes 390
Representing Contracts 394
Anatomy of a Domain Service 395
Avoiding Anemic Domain Models 395
Contrasting with Application Services 396
Utilizing Domain Services 397
In the Service Layer 397
In the Domain 398
Manually Wiring Up 399
Using Dependency Injection 400
Using a Service Locator 400
Applying Double Dispatch 401
Decoupling with Domain Events 402
Should Entities Even Know About Domain Services? 403
The Salient Points 403
CHAPTER 18: DOMAIN EVENTS 405
Essence of the Domain Events Pattern 406
Important Domain Occurrences That Have Already Happened 406
Reacting to Events 407
Optional Asynchrony 407
Internal vs External Events 408
Event Handling Actions 409
Invoke Domain Logic 409
Invoke Application Logic 410
Domain Events’ Implementation Patterns 410
Use the .Net Framework’s Events Model 410
Use an In‐Memory Bus 412
Udi Dahan’s Static DomainEvents Class 415
Handling Threading Issues 417
Avoid a Static Class by Using Method Injection 418
Return Domain Events 419
Use an IoC Container as an Event Dispatcher 421
Testing Domain Events 422
Unit Testing 422
Application Service Layer Testing 424
The Salient Points 425
CHAPTER 19: AGGREGATES 427
Managing Complex Object Graphs 428
Favoring a Single Traversal Direction 428
Qualifying Associations 430
Preferring IDs Over Object References 431
Aggregates 434
Design Around Domain Invariants 435
Higher Level of Domain Abstraction 435
Consistency Boundaries 435
Transactional Consistency Internally 436
Eventual Consistency Externally 439
Special Cases 440
Favor Smaller Aggregates 441
Large Aggregates Can Degrade Performance 441
Large Aggregates Are More Susceptible to Concurrency Conflicts 442
Large Aggregates May Not Scale Well 442
Defining Aggregate Boundaries 442
eBidder: The Online Auction Case Study 443
Aligning with Invariants 444
Aligning with Transactions and Consistency 446
Ignoring User Interface Influences 448
Avoiding Dumb Collections and Containers 448
Don’t Focus on HAS‐A Relationships 449
Refactoring to Aggregates 449
Satisfying Business Use Cases—Not Real Life 449
Implementing Aggregates 450
Selecting an Aggregate Root 450
Exposing Behavioral Interfaces 452
Protecting Internal State 453
Allowing Only Roots to Have Global Identity 454
Referencing Other Aggregates 454
Nothing Outside An Aggregate’s Boundary May Hold a Reference to Anything Inside 455
The Aggregate Root Can Hand Out Transient References to the Internal Domain Objects 456
Objects within the Aggregate Can Hold References to Other Aggregate Roots 456
Implementing Persistence 458
Access to Domain Objects for Reading Can Be at the Database Level 460
A Delete Operation Must Remove Everything within the Aggregate Boundary at Once 461
Avoiding Lazy Loading 461
Implementing Transactional Consistency 462
Implementing Eventual Consistency 463
Rules That Span Multiple Aggregates 463
Asynchronous Eventual Consistency 464
Implementing Concurrency 465
The Salient Points 468
CHAPTER 20: FACTORIES 469
The Role of a Factory 469
Separating Use from Construction 470
Encapsulating Internals 470
Hiding Decisions on Creation Type 472
Factory Methods on Aggregates 474
Factories for Reconstitution 475
Use Factories Pragmatically 477
The Salient Points 477
CHAPTER 21: REPOSITORIES 479
Repositories 479
A Misunderstood Pattern 481
Is the Repository an Antipattern? 481
The Difference between a Domain Model and a Persistence Model 482
The Generic Repository 483
Aggregate Persistence Strategies 486
Using a Persistence Framework That Can Map the Domain Model to the Data Model without Compromise 486
Using a Persistence Framework That Cannot Map the Domain Model Directly without Compromise 487
Public Getters and Setters 487
Using the Memento Pattern 488
Event Streams 49
Be Pragmatic 491
A Repository Is an Explicit Contract 492
Transaction Management and Units of Work 493
To Save or Not To Save 497
Persistence Frameworks That Track Domain Object Changes 497
Having to Explicitly Save Changes to Aggregates 498
The Repository as an Anticorruption Layer 499
Other Responsibilities of a Repository 500
Entity ID Generation 500
Collection Summaries 502
Concurrency 503
Audit Trails 506
Repository Antipatterns 506
Antipatterns: Don’t Support Ad Hoc Queries 506
Antipatterns: Lazy Loading Is Design Smell 507
Antipatterns: Don’t Use Repositories for Reporting Needs 507
Repository Implementations 508
Persistence Framework Can Map Domain Model to Data Model without Compromise 509
NHibernate Example 509
RavenDB Example 543
Persistence Framework Cannot Map Domain Model Directly without Compromise 557
Entity Framework Example 558
Micro ORM Example 577
The Salient Points 593
CHAPTER 22: EVENT SOURCING 595
The Limitations of Storing State as a Snapshot 596
Gaining Competitive Advantage by Storing State as a Stream of Events 597
Temporal Queries 597
Projections 599
Snapshots 599
Event‐Sourced Aggregates 600
Structuring 600
Adding Event‐Sourcing Capabilities 601
Exposing Expressive Domain‐Focused APIs 602
Adding Snapshot Support 604
Persisting and Rehydrating 605
Creating an Event-Sourcing Repository 605
Adding Snapshot Persistence and Reloading 607
Handling Concurrency 609
Testing 610
Building an Event Store 611
Designing a Storage Format 612
Creating Event Streams 614
Appending to Event Streams 614
Querying Event Streams 615
Adding Snapshot Support 616
Managing Concurrency 618
A SQL Server‐Based Event Store 621
Choosing a Schema 621
Creating a Stream 622
Saving Events 623
Loading Events from a Stream 624
Snapshots 625
Is Building Your Own Event Store a Good Idea? 627
Using the Purpose‐Built Event Store 627
Installing Greg Young’s Event Store 628
Using the C# Client Library 627
Running Temporal Queries 632
Querying a Single Stream 632
Querying Multiple Streams 634
Creating Projections 635
CQRS with Event Sourcing 637
Using Projections to Create View Caches 638
CQRS and Event Sourcing Synergy 638
Event Streams as Queues 639
No Two‐Phase Commits 639
Recapping the Benefits of Event Sourcing 639
Competitive Business Advantage 639
Expressive Behavior‐Focused Aggregates 639
Simplified Persistence 640
Superior Debugging 640
Weighing the Costs of Event Sourcing 640
Versioning 640
New Concepts to Learn and Skills to Hone 640
New Technologies to Learn and Master 641
Greater Data Storage Requirements 641
Additional Learning Resources 641
The Salient Points 641
PART IV: DESIGN PATTERNS FOR EFFECTIVE APPLICATIONS
CHAPTER 23: ARCHITECTING APPLICATION USER INTERFACES 645
Design Considerations 646
Owned UIs versus Composed UIs 646
Autonomous 646
Authoritative 647
Some Help Deciding 648
HTML APIs versus Data APIs 649
Client versus Server‐Side Aggregation/Coordination 649
Example 1: An HTML API‐Based, Server‐Side UI for Nondistributed Bounded Contexts 651
Example 2: A Data API‐Based, Client‐Side UI for Distributed Bounded Contexts 658
The Salient Points 667
CHAPTER 24: CQRS: AN ARCHITECTURE OF A BOUNDED CONTEXT 669
The Challenges of Maintaining a Single Model for Two Contexts 670
A Better Architecture for Complex Bounded Contexts 670
The Command Side: Business Tasks 672
Explicitly Modeling Intent 672
A Model Free from Presentational Distractions 674
Handling a Business Request 675
The Query Side: Domain Reporting 676
Reports Mapped Directly to the Data Model 676
Materialized Views Built from Domain Events 678
The Misconceptions of CQRS 679
CQRS Is Hard 679
CQRS Is Eventually Consistent 679
Your Models Need to Be Event Sourced 680
Commands Should Be Asynchronous 680
CQRS Only Works with Messaging Systems 680
You Need to Use Domain Events with CQRS 680
Patterns to Enable Your Application to Scale 680
Scaling the Read Side: An Eventually Consistent Read Model 681
The Impact to the User Experience 682
Use the Read Model to Consolidate Many Bounded Contexts 682
Using a Reporting Database or a Caching Layer 682
Scaling the Write Side: Using Asynchronous Commands 683
Command Validation 683
Impact to the User Experience 684
Scaling It All 684
The Salient Points 685
CHAPTER 25: COMMANDS: APPLICATION SERVICE PATTERNS FOR PROCESSING BUSINESS USE CASES 687
Differentiating Application Logic and Domain Logic 689
Application Logic 689
Infrastructural Concerns 690
Coordinating Full Business Use Cases 698
Application Services and Framework Integration 698
Domain Logic from an Application Service’s Perspective 700
Application Service Patterns 700
Command Processor 701
Publish/Subscribe 704
Request/Reply Pattern 706
async/await 708
Testing Application Services 709
Use Domain Terminology 709
Test as Much Functionality as Possible 710
The Salient Points 712
CHAPTER 26: QUERIES: DOMAIN REPORTING 713
Domain Reporting within a Bounded Context 714
Deriving Reports from Domain Objects 714
Using Simple Mappings 714
Using the Mediator Pattern 718
Going Directly to the Datastore 720
Querying a Datastore 721
Reading Denormalized View Caches 724
Building Projections from Event Streams 726
Setting Up ES for Projections 727
Creating Reporting Projections 728
Counting the Number of Events in a Stream 729
Creating As Many Streams As Required 729
Building a Report from Streams and Projections 730
Domain Reporting Across Bounded Contexts 733
Composed UI 733
Separate Reporting Context 734
The Salient Points 736
INDEX 737
INTRODUCTION xxxv PART I: THE PRINCIPLES AND PRACTICES OF DOMAIN
DRIVEN DESIGN CHAPTER 1: WHAT IS DOMAIN
DRIVEN DESIGN? 3 The Challenges of Creating Software for Complex Problem Domains 4 Code Created Without a Common Language 4 A Lack of Organization 5 The Ball of Mud Pattern Stifles Development 5 A Lack of Focus on the Problem Domain 6 How the Patterns of Domain
Driven Design Manage Complexity 6 The Strategic Patterns of DDD 6 Distilling the Problem Domain to Reveal What Is Important 7 Creating a Model to Solve Domain Problems 7 Using a Shared Language to Enable Modeling Collaboration 7 Isolate Models from Ambiguity and Corruption 8 Understanding the Relationships between Contexts 9 The Tactical Patterns of DDD 9 The Problem Space and the Solution Space 9 The Practices and Principles of Domain
Driven Design 11 Focusing on the Core Domain 11 Learning through Collaboration 11 Creating Models through Exploration and Experimentation 11 Communication 11 Understanding the Applicability of a Model 12 Constantly Evolving the Model 12 Popular Misconceptions of Domain
Driven Design 12 Tactical Patterns Are Key to DDD 12 DDD Is a Framework 13 DDD Is a Silver Bullet 13 The Salient Points 13 CHAPTER 2: DISTILLING THE PROBLEM DOMAIN 15 Knowledge Crunching and Collaboration 15 Reaching a Shared Understanding through a Shared Language 16 The Importance of Domain Knowledge 17 The Role of Business Analysts 17 An Ongoing Process 17 Gaining Domain Insight with Domain Experts 18 Domain Experts vs Stakeholders 18 Deeper Understanding for the Business 19 Engaging with Your Domain Experts 19 Patterns for Effective Knowledge Crunching 19 Focus on the Most Interesting Conversations 19 Start from the Use Cases 20 Ask Powerful Questions 20 Sketching 20 Class Responsibility Collaboration Cards 21 Defer the Naming of Concepts in Your Model 21 Behavior
Driven Development 22 Rapid Prototyping 23 Look at Paper
Based Systems 24 Look For Existing Models 24 Understanding Intent 24 Event Storming 25 Impact Mapping 25 Understanding the Business Model 27 Deliberate Discovery 28 Model Exploration Whirlpool 29 The Salient Points 29 CHAPTER 3: FOCUSING ON THE CORE DOMAIN 31 Why Decompose a Problem Domain? 31 How to Capture the Essence of the Problem 32 Look Beyond Requirements 32 Capture the Domain Vision for a Shared Understanding of What Is Core 32 How to Focus on the Core Problem 33 Distilling a Problem Domain 34 Core Domains 35 Treat Your Core Domain as a Product Rather than a Project 36 Generic Domains 37 Supporting Domains 37 How Subdomains Shape a Solution 37 Not All Parts of a System will be Well Designed 37 Focus on Clean Boundaries over Perfect Models 38 The Core Domain Doesn't Always Have to Be Perfect the First Time 39 Build Subdomains for Replacement Rather than Reuse 39 What if You Have no Core Domain? 39 The Salient Points 40 CHAPTER 4: MODEL
DRIVEN DESIGN 41 What Is a Domain Model? 42 The Domain versus the Domain Model 42 The Analysis Model 43 The Code Model 43 The Code Model Is the Primary Expression of the Domain Model 44 Model
Driven Design 44 The Challenges with Upfront Design 44 Team Modeling 45 Using a Ubiquitous Language to Bind the Analysis to the Code Model 47 A Language Will Outlive Your Software 47 The Language of the Business 48 Translation between the Developers and the Business 48 Collaborating on a Ubiquitous Language 48 Carving Out a Language by Working with Concrete Examples 49 Teach Your Domain Experts to Focus on the Problem and Not Jump to a Solution 50 Best Practices for Shaping the Language 51 How to Create Effective Domain Models 52 Don't Let the Truth Get in the Way of a Good Model 52 Model Only What Is Relevant 54 Domain Models Are Temporarily Useful 54 Be Explicit with Terminology 54 Limit Your Abstractions 54 Focus Your Code at the Right Level of Abstraction 55 Abstract Behavior Not Implementations 55 Implement the Model in Code Early and Often 56 Don't Stop at the First Good Idea 56 When to Apply Model
Driven Design 56 If It's Not Worth the Effort Don't Try and Model It 56 Focus on the Core Domain 57 The Salient Points 57 CHAPTER 5: DOMAIN MODEL IMPLEMENTATION PATTERNS 59 The Domain Layer 60 Domain Model Implementation Patterns 60 Domain Model 62 Transaction Script 65 Table Module 67 Active Record 67 Anemic Domain Model 67 Anemic Domain Model and Functional Programming 68 The Salient Points 71 CHAPTER 6: MAINTAINING THE INTEGRITY OF DOMAIN MODELS WITH BOUNDED CONTEXTS 73 The Challenges of a Single Model 74 A Model Can Grow in Complexity 74 Multiple Teams Working on a Single Model 74 Ambiguity in the Language of the Model 75 The Applicability of a Domain Concept 76 Integration with Legacy Code or Third Party Code 78 Your Domain Model Is not Your Enterprise Model 79 Use Bounded Contexts to Divide and Conquer a Large Model 79 Defining a Model's Boundary 82 Define Boundaries around Language 82 Align to Business Capabilities 83 Create Contexts around Teams 83 Try to Retain Some Communication between Teams 84 Context Game 85 The Difference between a Subdomain and a Bounded Context 85 Implementing Bounded Contexts 85 The Salient Points 89 CHAPTER 7: CONTEXT MAPPING 91 A Reality Map 92 The Technical Reality 92 The Organizational Reality 93 Mapping a Relevant Reality 94 X Marks the Spot of the Core Domain 94 Recognising the Relationships between Bounded Contexts 95 Anticorruption Layer 95 Shared Kernel 96 Open Host Service 97 Separate Ways 97 Partnership 98 An Upstream/Downstream Relationship 98 Customer
Supplier 99 Conformist 100 Communicating the Context Map 100 The Strategic Importance of Context Maps 101 Retaining Integrity 101 The Basis for a Plan of Attack 101 Understanding Ownership and Responsibility 101 Revealing Areas of Confusion in Business Work Flow 102 Identifying Nontechnical Obstacles 102 Encourages Good Communication 102 Helps On
Board New Starters 102 The Salient Points 103 CHAPTER 8: APPLICATION ARCHITECTURE 105 Application Architecture 105 Separating the Concerns of Your Application 106 Abstraction from the Complexities of the Domain 106 A Layered Architecture 106 Dependency Inversion 107 The Domain Layer 107 The Application Service Layer 108 The Infrastructural Layers 108 Communication Across Layers 108 Testing in Isolation 109 Don t Share Data Schema between Bounded Contexts 109 Application Architectures versus Architectures for Bounded Contexts 111 Application Services 112 Application Logic versus Domain Logic 114 Defining and Exposing Capabilities 114 Business Use Case Coordination 115 Application Services Represent Use Cases, Not Create, Read, Update, and Delete 115 Domain Layer As an Implementation Detail 115 Domain Reporting 116 Read Models versus Transactional Models 116 Application Clients 117 The Salient Points 120 CHAPTER 9: COMMON PROBLEMS FOR TEAMS STARTING OUT WITH DOMAIN
DRIVEN DESIGN 121 Overemphasizing the Importance of Tactical Patterns 122 Using the Same Architecture for All Bounded Contexts 122 Striving for Tactical Pattern Perfection 122 Mistaking the Building Blocks for the Value of DDD 123 Focusing on Code Rather Than the Principles of DDD 123 Missing the Real Value of DDD: Collaboration, Communication, and Context 124 Producing a Big Ball of Mud Due to Underestimating the Importance of Context 124 Causing Ambiguity and Misinterpretations by Failing to Create a UL 125 Designing Technical
Focused Solutions Due to a Lack of Collaboration 125 Spending Too Much Time on What's Not Important 126 Making Simple Problems Complex 126 Applying DDD Principles to a Trivial Domain with Little Business Expectation 126 Disregarding CRUD as an Antipattern 127 Using the Domain Model Pattern for Every Bounded Context 127 Ask Yourself: Is It Worth This Extra Complexity? 127 Underestimating the Cost of Applying DDD 127 Trying to Succeed Without a Motivated and Focused Team 128 Attempting Collaboration When a Domain Expert Is Not Behind the Project 128 Learning in a Noniterative Development Methodology 128 Applying DDD to Every Problem 129 Sacrificing Pragmatism for Needless Purity 129 Wasted Effort by Seeking Validation 129 Always Striving for Beautiful Code 130 DDD Is About Providing Value 130 The Salient Points 130 CHAPTER 10: APPLYING THE PRINCIPLES, PRACTICES, AND PATTERNS OF DDD 131 Selling DDD 132 Educating Your Team 132 Speaking to Your Business 132 Applying the Principles of DDD 133 Understand the Vision 133 Capture the Required Behaviors 134 Distilling the Problem Space 134 Focus on What Is Important 134 Understand the Reality of the Landscape 135 Modeling a Solution 135 All Problems Are Not Created Equal 136 Engaging with an Expert 136 Select a Behavior and Model Around a Concrete Scenario 137 Collaborate with the Domain Expert on the Most Interesting Parts 137 Evolve UL to Remove Ambiguity 138 Throw Away Your First Model, and Your Second 138 Implement the Model in Code 139 Creating a Domain Model 139 Keep the Solution Simple and Your Code Boring 139 Carve Out an Area of Safety 140 Integrate the Model Early and Often 140 Nontechnical Refactoring 140 Decompose Your Solution Space 140 Rinse and Repeat 141 Exploration and Experimentation 142 Challenge Your Assumptions 142 Modeling Is a Continuous Activity 142 There Are No Wrong Models 142 Supple Code Aids Discovery 143 Making the Implicit Explicit 143 Tackling Ambiguity 144 Give Things a Name 145 A Problem Solver First, A Technologist Second 146 Don't Solve All the Problems 146 How Do I Know That I Am Doing It Right? 146 Good Is Good Enough 147 Practice, Practice, Practice 147 The Salient Points 147 PART II: STRATEGIC PATTERNS: COMMUNICATING BETWEEN BOUNDED CONTEXTS CHAPTER 11: INTRODUCTION TO BOUNDED CONTEXT INTEGRATION 151 How to Integrate Bounded Contexts 152 Bounded Contexts Are Autonomous 153 The Challenges of Integrating Bounded Contexts at the Code Level 153 Multiple Bounded Contexts Exist within a Solution 153 Namespaces or Projects to Keep Bounded Contexts Separate 154 Integrating via the Database 155 Multiple Teams Working in a Single Codebase 156 Models Blur 156 Use Physical Boundaries to Enforce Clean Models 157 Integrating with Legacy Systems 158 Bubble Context 158 Autonomous Bubble Context 158 Exposing Legacy Systems as Services 160 Integrating Distributed Bounded Contexts 161 Integration Strategies for Distributed Bounded Contexts 161 Database Integration 162 Flat File Integration 163 RPC 164 Messaging 165 REST 165 The Challenges of DDD with Distributed Systems 165 The Problem with RPC 166 RPC Is Harder to Make Resilient 167 RPC Costs More to Scale 167 RPC Involves Tight Coupling 168 Distributed Transactions Hurt Scalability and Reliability 169 Bounded Contexts Don't Have to Be Consistent with Each Other 169 Eventual Consistency 169 Event
Driven Reactive DDD 170 Demonstrating the Resilience and Scalability of Reactive Solutions 171 Challenges and Trade
Offs of Asynchronous Messaging 173 Is RPC Still Relevant? 173 SOA and Reactive DDD 174 View Your Bounded Contexts as SOA Services 175 Decompose Bounded Contexts into Business Components 175 Decompose Business Components into Components 176 Going Even Further with Micro Service Architecture 178 The Salient Points 180 CHAPTER 12: INTEGRATING VIA MESSAGING 181 Messaging Fundamentals 182 Message Bus 182 Reliable Messaging 184 Store
and
Forward 184 Commands and Events 185 Eventual Consistency 186 Building an E
Commerce Application with NServiceBus 186 Designing the System 187 Domain
Driven Design 187 Containers Diagrams 188 Evolutionary Architecture 191 Sending Commands from a Web Application 192 Creating a Web Application to Send Messages with NServiceBus 192 Sending Commands 197 Handling Commands and Publishing Events 200 Creating an NServiceBus Server to Handle Commands 200 Configuring the Solution for Testing and Debugging 201 Publishing Events 204 Subscribing to Events 206 Making External HTTP Calls Reliable with Messaging Gateways 208 Messaging Gateways Improve Fault Tolerance 208 Implementing a Messaging Gateway 209 Controlling Message Retries 212 Eventual Consistency in Practice 215 Dealing with Inconsistency 215 Rolling Forward into New States 215 Bounded Contexts Store All the Data They Need Locally 216 Storage Is Cheap-Keep a Local Copy 217 Common Data Duplication Concerns 223 Pulling It All Together in the UI 224 Business Components Need Their Own APIs 225 Be Wary of Server
Side Orchestration 226 UI Composition with AJAX Data 226 UI Composition with AJAX HTML 226 Sharing Your APIs with the Outside World 227 Maintaining a Messaging Application 227 Message Versioning 228 Backward
Compatible Message Versioning 228 Handling Versioning with NServiceBus's Polymorphic Handlers 229 Monitoring and Scaling 233 Monitoring Errors 233 Monitoring SLAs 234 Scaling Out 235 Integrating a Bounded Context with Mass Transit 235 Messaging Bridge 236 Mass Transit 236 Installing and Configuring Mass Transit 236 Declaring Messages for Use by Mass Transit 238 Creating a Message Handler 239 Subscribing to Events 239 Linking the Systems with a Messaging Bridge 240 Publishing Events 242 Testing It Out 243 Where to Learn More about Mass Transit 243 The Salient Points 243 CHAPTER 13: INTEGRATING VIA HTTP WITH RPC AND REST 245 Why Prefer HTTP? 247 No Platform Coupling 247 Everyone Understands HTTP 247 Lots of Mature Tooling and Libraries 247 Dogfooding Your APIs 247 RPC 248 Implementing RPC over HTTP 248 SOAP 249 Plain XML or JSON: The Modern Approach to RPC 259 Choosing a Flavor of RPC 263 REST 264 Demystifying REST 264 Resources 264 Hypermedia 265 Statelessness 265 REST Fully Embraces HTTP 266 What REST Is Not 267 REST for Bounded Context Integration 268 Designing for REST 268 Building Event
Driven REST Systems with ASP.NET Web API 273 Maintaining REST Applications 303 Versioning 303 Monitoring and Metrics 303 Drawbacks with REST for Bounded Context Integration 304 Less Fault Tolerance Out of the Box 304 Eventual Consistency 304 The Salient Points 305 PART III: TACTICAL PATTERNS: CREATING EFFECTIVE DOMAIN MODELS CHAPTER 14: INTRODUCING THE DOMAIN MODELING BUILDING BLOCKS 309 Tactical Patterns 310 Patterns to Model Your Domain 310 Entities 310 Value Objects 314 Domain Services 317 Modules 318 Lifecycle Patterns 318 Aggregates 318 Factories 322 Repositories 323 Emerging Patterns 324 Domain Events 324 Event Sourcing 326 The Salient Points 327 CHAPTER 15: VALUE OBJECTS 329 When to Use a Value Object 330 Representing a Descriptive, Identity
Less Concept 330 Enhancing Explicitness 331 Defining Characteristics 333 Identity
Less 333 Attribute
Based Equality 333 Behavior
Rich 337 Cohesive 337 Immutable 337 Combinable 339 Self
Validating 341 Testable 344 Common Modeling Patterns 345 Static Factory Methods 345 Micro Types (Also Known as Tiny Types) 347 Collection Aversion 349 Persistence 35 NoSQL 352 SQL 353 Flat Denormalization 353 Normalizing into Separate Tables 357 The Salient Points 359 CHAPTER 16: ENTITIES 36 Understanding Entities 362 Domain Concepts with Identity and Continuity 362 Context
Dependent 363 Implementing Entities 363 Assigning Identifiers 363 Natural Keys 363 Arbitrarily Generated IDs 364 Datastore
Generated IDs 368 Pushing Behavior into Value Objects and Domain Services 369 Validating and Enforcing Invariants 371 Focusing on Behavior, Not Data 374 Avoiding the "Model the Real
World" Fallacy 377 Designing for Distribution 378 Common Entity Modeling Principles and Patterns 380 Implementing Validation and Invariants with Specifications 380 Avoid the State Pattern; Use Explicit Modeling 382 Avoiding Getters and Setters with the Memento Pattern 385 Favor Hidden
Side
Effect
Free Functions 386 The Salient Points 388 CHAPTER 17: DOMAIN SERVICES 389 Understanding Domain Services 390 When to Use a Domain Service 390 Encapsulating Business Policies and Processes 390 Representing Contracts 394 Anatomy of a Domain Service 395 Avoiding Anemic Domain Models 395 Contrasting with Application Services 396 Utilizing Domain Services 397 In the Service Layer 397 In the Domain 398 Manually Wiring Up 399 Using Dependency Injection 400 Using a Service Locator 400 Applying Double Dispatch 401 Decoupling with Domain Events 402 Should Entities Even Know About Domain Services? 403 The Salient Points 403 CHAPTER 18: DOMAIN EVENTS 405 Essence of the Domain Events Pattern 406 Important Domain Occurrences That Have Already Happened 406 Reacting to Events 407 Optional Asynchrony 407 Internal vs External Events 408 Event Handling Actions 409 Invoke Domain Logic 409 Invoke Application Logic 410 Domain Events' Implementation Patterns 410 Use the .Net Framework's Events Model 410 Use an In
Memory Bus 412 Udi Dahan's Static DomainEvents Class 415 Handling Threading Issues 417 Avoid a Static Class by Using Method Injection 418 Return Domain Events 419 Use an IoC Container as an Event Dispatcher 421 Testing Domain Events 422 Unit Testing 422 Application Service Layer Testing 424 The Salient Points 425 CHAPTER 19: AGGREGATES 427 Managing Complex Object Graphs 428 Favoring a Single Traversal Direction 428 Qualifying Associations 430 Preferring IDs Over Object References 431 Aggregates 434 Design Around Domain Invariants 435 Higher Level of Domain Abstraction 435 Consistency Boundaries 435 Transactional Consistency Internally 436 Eventual Consistency Externally 439 Special Cases 440 Favor Smaller Aggregates 441 Large Aggregates Can Degrade Performance 441 Large Aggregates Are More Susceptible to Concurrency Conflicts 442 Large Aggregates May Not Scale Well 442 Defining Aggregate Boundaries 442 eBidder: The Online Auction Case Study 443 Aligning with Invariants 444 Aligning with Transactions and Consistency 446 Ignoring User Interface Influences 448 Avoiding Dumb Collections and Containers 448 Don't Focus on HAS
A Relationships 449 Refactoring to Aggregates 449 Satisfying Business Use Cases-Not Real Life 449 Implementing Aggregates 450 Selecting an Aggregate Root 450 Exposing Behavioral Interfaces 452 Protecting Internal State 453 Allowing Only Roots to Have Global Identity 454 Referencing Other Aggregates 454 Nothing Outside An Aggregate's Boundary May Hold a Reference to Anything Inside 455 The Aggregate Root Can Hand Out Transient References to the Internal Domain Objects 456 Objects within the Aggregate Can Hold References to Other Aggregate Roots 456 Implementing Persistence 458 Access to Domain Objects for Reading Can Be at the Database Level 460 A Delete Operation Must Remove Everything within the Aggregate Boundary at Once 461 Avoiding Lazy Loading 461 Implementing Transactional Consistency 462 Implementing Eventual Consistency 463 Rules That Span Multiple Aggregates 463 Asynchronous Eventual Consistency 464 Implementing Concurrency 465 The Salient Points 468 CHAPTER 20: FACTORIES 469 The Role of a Factory 469 Separating Use from Construction 470 Encapsulating Internals 470 Hiding Decisions on Creation Type 472 Factory Methods on Aggregates 474 Factories for Reconstitution 475 Use Factories Pragmatically 477 The Salient Points 477 CHAPTER 21: REPOSITORIES 479 Repositories 479 A Misunderstood Pattern 481 Is the Repository an Antipattern? 481 The Difference between a Domain Model and a Persistence Model 482 The Generic Repository 483 Aggregate Persistence Strategies 486 Using a Persistence Framework That Can Map the Domain Model to the Data Model without Compromise 486 Using a Persistence Framework That Cannot Map the Domain Model Directly without Compromise 487 Public Getters and Setters 487 Using the Memento Pattern 488 Event Streams 49 Be Pragmatic 491 A Repository Is an Explicit Contract 492 Transaction Management and Units of Work 493 To Save or Not To Save 497 Persistence Frameworks That Track Domain Object Changes 497 Having to Explicitly Save Changes to Aggregates 498 The Repository as an Anticorruption Layer 499 Other Responsibilities of a Repository 500 Entity ID Generation 500 Collection Summaries 502 Concurrency 503 Audit Trails 506 Repository Antipatterns 506 Antipatterns: Don't Support Ad Hoc Queries 506 Antipatterns: Lazy Loading Is Design Smell 507 Antipatterns: Don't Use Repositories for Reporting Needs 507 Repository Implementations 508 Persistence Framework Can Map Domain Model to Data Model without Compromise 509 NHibernate Example 509 RavenDB Example 543 Persistence Framework Cannot Map Domain Model Directly without Compromise 557 Entity Framework Example 558 Micro ORM Example 577 The Salient Points 593 CHAPTER 22: EVENT SOURCING 595 The Limitations of Storing State as a Snapshot 596 Gaining Competitive Advantage by Storing State as a Stream of Events 597 Temporal Queries 597 Projections 599 Snapshots 599 Event
Sourced Aggregates 600 Structuring 600 Adding Event
Sourcing Capabilities 601 Exposing Expressive Domain
Focused APIs 602 Adding Snapshot Support 604 Persisting and Rehydrating 605 Creating an Event-Sourcing Repository 605 Adding Snapshot Persistence and Reloading 607 Handling Concurrency 609 Testing 610 Building an Event Store 611 Designing a Storage Format 612 Creating Event Streams 614 Appending to Event Streams 614 Querying Event Streams 615 Adding Snapshot Support 616 Managing Concurrency 618 A SQL Server
Based Event Store 621 Choosing a Schema 621 Creating a Stream 622 Saving Events 623 Loading Events from a Stream 624 Snapshots 625 Is Building Your Own Event Store a Good Idea? 627 Using the Purpose
Built Event Store 627 Installing Greg Young's Event Store 628 Using the C# Client Library 627 Running Temporal Queries 632 Querying a Single Stream 632 Querying Multiple Streams 634 Creating Projections 635 CQRS with Event Sourcing 637 Using Projections to Create View Caches 638 CQRS and Event Sourcing Synergy 638 Event Streams as Queues 639 No TwöPhase Commits 639 Recapping the Benefits of Event Sourcing 639 Competitive Business Advantage 639 Expressive Behavior
Focused Aggregates 639 Simplified Persistence 640 Superior Debugging 640 Weighing the Costs of Event Sourcing 640 Versioning 640 New Concepts to Learn and Skills to Hone 640 New Technologies to Learn and Master 641 Greater Data Storage Requirements 641 Additional Learning Resources 641 The Salient Points 641 PART IV: DESIGN PATTERNS FOR EFFECTIVE APPLICATIONS CHAPTER 23: ARCHITECTING APPLICATION USER INTERFACES 645 Design Considerations 646 Owned UIs versus Composed UIs 646 Autonomous 646 Authoritative 647 Some Help Deciding 648 HTML APIs versus Data APIs 649 Client versus Server
Side Aggregation/Coordination 649 Example 1: An HTML API
Based, Server
Side UI for Nondistributed Bounded Contexts 651 Example 2: A Data API
Based, Client
Side UI for Distributed Bounded Contexts 658 The Salient Points 667 CHAPTER 24: CQRS: AN ARCHITECTURE OF A BOUNDED CONTEXT 669 The Challenges of Maintaining a Single Model for Two Contexts 670 A Better Architecture for Complex Bounded Contexts 670 The Command Side: Business Tasks 672 Explicitly Modeling Intent 672 A Model Free from Presentational Distractions 674 Handling a Business Request 675 The Query Side: Domain Reporting 676 Reports Mapped Directly to the Data Model 676 Materialized Views Built from Domain Events 678 The Misconceptions of CQRS 679 CQRS Is Hard 679 CQRS Is Eventually Consistent 679 Your Models Need to Be Event Sourced 680 Commands Should Be Asynchronous 680 CQRS Only Works with Messaging Systems 680 You Need to Use Do
DRIVEN DESIGN CHAPTER 1: WHAT IS DOMAIN
DRIVEN DESIGN? 3 The Challenges of Creating Software for Complex Problem Domains 4 Code Created Without a Common Language 4 A Lack of Organization 5 The Ball of Mud Pattern Stifles Development 5 A Lack of Focus on the Problem Domain 6 How the Patterns of Domain
Driven Design Manage Complexity 6 The Strategic Patterns of DDD 6 Distilling the Problem Domain to Reveal What Is Important 7 Creating a Model to Solve Domain Problems 7 Using a Shared Language to Enable Modeling Collaboration 7 Isolate Models from Ambiguity and Corruption 8 Understanding the Relationships between Contexts 9 The Tactical Patterns of DDD 9 The Problem Space and the Solution Space 9 The Practices and Principles of Domain
Driven Design 11 Focusing on the Core Domain 11 Learning through Collaboration 11 Creating Models through Exploration and Experimentation 11 Communication 11 Understanding the Applicability of a Model 12 Constantly Evolving the Model 12 Popular Misconceptions of Domain
Driven Design 12 Tactical Patterns Are Key to DDD 12 DDD Is a Framework 13 DDD Is a Silver Bullet 13 The Salient Points 13 CHAPTER 2: DISTILLING THE PROBLEM DOMAIN 15 Knowledge Crunching and Collaboration 15 Reaching a Shared Understanding through a Shared Language 16 The Importance of Domain Knowledge 17 The Role of Business Analysts 17 An Ongoing Process 17 Gaining Domain Insight with Domain Experts 18 Domain Experts vs Stakeholders 18 Deeper Understanding for the Business 19 Engaging with Your Domain Experts 19 Patterns for Effective Knowledge Crunching 19 Focus on the Most Interesting Conversations 19 Start from the Use Cases 20 Ask Powerful Questions 20 Sketching 20 Class Responsibility Collaboration Cards 21 Defer the Naming of Concepts in Your Model 21 Behavior
Driven Development 22 Rapid Prototyping 23 Look at Paper
Based Systems 24 Look For Existing Models 24 Understanding Intent 24 Event Storming 25 Impact Mapping 25 Understanding the Business Model 27 Deliberate Discovery 28 Model Exploration Whirlpool 29 The Salient Points 29 CHAPTER 3: FOCUSING ON THE CORE DOMAIN 31 Why Decompose a Problem Domain? 31 How to Capture the Essence of the Problem 32 Look Beyond Requirements 32 Capture the Domain Vision for a Shared Understanding of What Is Core 32 How to Focus on the Core Problem 33 Distilling a Problem Domain 34 Core Domains 35 Treat Your Core Domain as a Product Rather than a Project 36 Generic Domains 37 Supporting Domains 37 How Subdomains Shape a Solution 37 Not All Parts of a System will be Well Designed 37 Focus on Clean Boundaries over Perfect Models 38 The Core Domain Doesn't Always Have to Be Perfect the First Time 39 Build Subdomains for Replacement Rather than Reuse 39 What if You Have no Core Domain? 39 The Salient Points 40 CHAPTER 4: MODEL
DRIVEN DESIGN 41 What Is a Domain Model? 42 The Domain versus the Domain Model 42 The Analysis Model 43 The Code Model 43 The Code Model Is the Primary Expression of the Domain Model 44 Model
Driven Design 44 The Challenges with Upfront Design 44 Team Modeling 45 Using a Ubiquitous Language to Bind the Analysis to the Code Model 47 A Language Will Outlive Your Software 47 The Language of the Business 48 Translation between the Developers and the Business 48 Collaborating on a Ubiquitous Language 48 Carving Out a Language by Working with Concrete Examples 49 Teach Your Domain Experts to Focus on the Problem and Not Jump to a Solution 50 Best Practices for Shaping the Language 51 How to Create Effective Domain Models 52 Don't Let the Truth Get in the Way of a Good Model 52 Model Only What Is Relevant 54 Domain Models Are Temporarily Useful 54 Be Explicit with Terminology 54 Limit Your Abstractions 54 Focus Your Code at the Right Level of Abstraction 55 Abstract Behavior Not Implementations 55 Implement the Model in Code Early and Often 56 Don't Stop at the First Good Idea 56 When to Apply Model
Driven Design 56 If It's Not Worth the Effort Don't Try and Model It 56 Focus on the Core Domain 57 The Salient Points 57 CHAPTER 5: DOMAIN MODEL IMPLEMENTATION PATTERNS 59 The Domain Layer 60 Domain Model Implementation Patterns 60 Domain Model 62 Transaction Script 65 Table Module 67 Active Record 67 Anemic Domain Model 67 Anemic Domain Model and Functional Programming 68 The Salient Points 71 CHAPTER 6: MAINTAINING THE INTEGRITY OF DOMAIN MODELS WITH BOUNDED CONTEXTS 73 The Challenges of a Single Model 74 A Model Can Grow in Complexity 74 Multiple Teams Working on a Single Model 74 Ambiguity in the Language of the Model 75 The Applicability of a Domain Concept 76 Integration with Legacy Code or Third Party Code 78 Your Domain Model Is not Your Enterprise Model 79 Use Bounded Contexts to Divide and Conquer a Large Model 79 Defining a Model's Boundary 82 Define Boundaries around Language 82 Align to Business Capabilities 83 Create Contexts around Teams 83 Try to Retain Some Communication between Teams 84 Context Game 85 The Difference between a Subdomain and a Bounded Context 85 Implementing Bounded Contexts 85 The Salient Points 89 CHAPTER 7: CONTEXT MAPPING 91 A Reality Map 92 The Technical Reality 92 The Organizational Reality 93 Mapping a Relevant Reality 94 X Marks the Spot of the Core Domain 94 Recognising the Relationships between Bounded Contexts 95 Anticorruption Layer 95 Shared Kernel 96 Open Host Service 97 Separate Ways 97 Partnership 98 An Upstream/Downstream Relationship 98 Customer
Supplier 99 Conformist 100 Communicating the Context Map 100 The Strategic Importance of Context Maps 101 Retaining Integrity 101 The Basis for a Plan of Attack 101 Understanding Ownership and Responsibility 101 Revealing Areas of Confusion in Business Work Flow 102 Identifying Nontechnical Obstacles 102 Encourages Good Communication 102 Helps On
Board New Starters 102 The Salient Points 103 CHAPTER 8: APPLICATION ARCHITECTURE 105 Application Architecture 105 Separating the Concerns of Your Application 106 Abstraction from the Complexities of the Domain 106 A Layered Architecture 106 Dependency Inversion 107 The Domain Layer 107 The Application Service Layer 108 The Infrastructural Layers 108 Communication Across Layers 108 Testing in Isolation 109 Don t Share Data Schema between Bounded Contexts 109 Application Architectures versus Architectures for Bounded Contexts 111 Application Services 112 Application Logic versus Domain Logic 114 Defining and Exposing Capabilities 114 Business Use Case Coordination 115 Application Services Represent Use Cases, Not Create, Read, Update, and Delete 115 Domain Layer As an Implementation Detail 115 Domain Reporting 116 Read Models versus Transactional Models 116 Application Clients 117 The Salient Points 120 CHAPTER 9: COMMON PROBLEMS FOR TEAMS STARTING OUT WITH DOMAIN
DRIVEN DESIGN 121 Overemphasizing the Importance of Tactical Patterns 122 Using the Same Architecture for All Bounded Contexts 122 Striving for Tactical Pattern Perfection 122 Mistaking the Building Blocks for the Value of DDD 123 Focusing on Code Rather Than the Principles of DDD 123 Missing the Real Value of DDD: Collaboration, Communication, and Context 124 Producing a Big Ball of Mud Due to Underestimating the Importance of Context 124 Causing Ambiguity and Misinterpretations by Failing to Create a UL 125 Designing Technical
Focused Solutions Due to a Lack of Collaboration 125 Spending Too Much Time on What's Not Important 126 Making Simple Problems Complex 126 Applying DDD Principles to a Trivial Domain with Little Business Expectation 126 Disregarding CRUD as an Antipattern 127 Using the Domain Model Pattern for Every Bounded Context 127 Ask Yourself: Is It Worth This Extra Complexity? 127 Underestimating the Cost of Applying DDD 127 Trying to Succeed Without a Motivated and Focused Team 128 Attempting Collaboration When a Domain Expert Is Not Behind the Project 128 Learning in a Noniterative Development Methodology 128 Applying DDD to Every Problem 129 Sacrificing Pragmatism for Needless Purity 129 Wasted Effort by Seeking Validation 129 Always Striving for Beautiful Code 130 DDD Is About Providing Value 130 The Salient Points 130 CHAPTER 10: APPLYING THE PRINCIPLES, PRACTICES, AND PATTERNS OF DDD 131 Selling DDD 132 Educating Your Team 132 Speaking to Your Business 132 Applying the Principles of DDD 133 Understand the Vision 133 Capture the Required Behaviors 134 Distilling the Problem Space 134 Focus on What Is Important 134 Understand the Reality of the Landscape 135 Modeling a Solution 135 All Problems Are Not Created Equal 136 Engaging with an Expert 136 Select a Behavior and Model Around a Concrete Scenario 137 Collaborate with the Domain Expert on the Most Interesting Parts 137 Evolve UL to Remove Ambiguity 138 Throw Away Your First Model, and Your Second 138 Implement the Model in Code 139 Creating a Domain Model 139 Keep the Solution Simple and Your Code Boring 139 Carve Out an Area of Safety 140 Integrate the Model Early and Often 140 Nontechnical Refactoring 140 Decompose Your Solution Space 140 Rinse and Repeat 141 Exploration and Experimentation 142 Challenge Your Assumptions 142 Modeling Is a Continuous Activity 142 There Are No Wrong Models 142 Supple Code Aids Discovery 143 Making the Implicit Explicit 143 Tackling Ambiguity 144 Give Things a Name 145 A Problem Solver First, A Technologist Second 146 Don't Solve All the Problems 146 How Do I Know That I Am Doing It Right? 146 Good Is Good Enough 147 Practice, Practice, Practice 147 The Salient Points 147 PART II: STRATEGIC PATTERNS: COMMUNICATING BETWEEN BOUNDED CONTEXTS CHAPTER 11: INTRODUCTION TO BOUNDED CONTEXT INTEGRATION 151 How to Integrate Bounded Contexts 152 Bounded Contexts Are Autonomous 153 The Challenges of Integrating Bounded Contexts at the Code Level 153 Multiple Bounded Contexts Exist within a Solution 153 Namespaces or Projects to Keep Bounded Contexts Separate 154 Integrating via the Database 155 Multiple Teams Working in a Single Codebase 156 Models Blur 156 Use Physical Boundaries to Enforce Clean Models 157 Integrating with Legacy Systems 158 Bubble Context 158 Autonomous Bubble Context 158 Exposing Legacy Systems as Services 160 Integrating Distributed Bounded Contexts 161 Integration Strategies for Distributed Bounded Contexts 161 Database Integration 162 Flat File Integration 163 RPC 164 Messaging 165 REST 165 The Challenges of DDD with Distributed Systems 165 The Problem with RPC 166 RPC Is Harder to Make Resilient 167 RPC Costs More to Scale 167 RPC Involves Tight Coupling 168 Distributed Transactions Hurt Scalability and Reliability 169 Bounded Contexts Don't Have to Be Consistent with Each Other 169 Eventual Consistency 169 Event
Driven Reactive DDD 170 Demonstrating the Resilience and Scalability of Reactive Solutions 171 Challenges and Trade
Offs of Asynchronous Messaging 173 Is RPC Still Relevant? 173 SOA and Reactive DDD 174 View Your Bounded Contexts as SOA Services 175 Decompose Bounded Contexts into Business Components 175 Decompose Business Components into Components 176 Going Even Further with Micro Service Architecture 178 The Salient Points 180 CHAPTER 12: INTEGRATING VIA MESSAGING 181 Messaging Fundamentals 182 Message Bus 182 Reliable Messaging 184 Store
and
Forward 184 Commands and Events 185 Eventual Consistency 186 Building an E
Commerce Application with NServiceBus 186 Designing the System 187 Domain
Driven Design 187 Containers Diagrams 188 Evolutionary Architecture 191 Sending Commands from a Web Application 192 Creating a Web Application to Send Messages with NServiceBus 192 Sending Commands 197 Handling Commands and Publishing Events 200 Creating an NServiceBus Server to Handle Commands 200 Configuring the Solution for Testing and Debugging 201 Publishing Events 204 Subscribing to Events 206 Making External HTTP Calls Reliable with Messaging Gateways 208 Messaging Gateways Improve Fault Tolerance 208 Implementing a Messaging Gateway 209 Controlling Message Retries 212 Eventual Consistency in Practice 215 Dealing with Inconsistency 215 Rolling Forward into New States 215 Bounded Contexts Store All the Data They Need Locally 216 Storage Is Cheap-Keep a Local Copy 217 Common Data Duplication Concerns 223 Pulling It All Together in the UI 224 Business Components Need Their Own APIs 225 Be Wary of Server
Side Orchestration 226 UI Composition with AJAX Data 226 UI Composition with AJAX HTML 226 Sharing Your APIs with the Outside World 227 Maintaining a Messaging Application 227 Message Versioning 228 Backward
Compatible Message Versioning 228 Handling Versioning with NServiceBus's Polymorphic Handlers 229 Monitoring and Scaling 233 Monitoring Errors 233 Monitoring SLAs 234 Scaling Out 235 Integrating a Bounded Context with Mass Transit 235 Messaging Bridge 236 Mass Transit 236 Installing and Configuring Mass Transit 236 Declaring Messages for Use by Mass Transit 238 Creating a Message Handler 239 Subscribing to Events 239 Linking the Systems with a Messaging Bridge 240 Publishing Events 242 Testing It Out 243 Where to Learn More about Mass Transit 243 The Salient Points 243 CHAPTER 13: INTEGRATING VIA HTTP WITH RPC AND REST 245 Why Prefer HTTP? 247 No Platform Coupling 247 Everyone Understands HTTP 247 Lots of Mature Tooling and Libraries 247 Dogfooding Your APIs 247 RPC 248 Implementing RPC over HTTP 248 SOAP 249 Plain XML or JSON: The Modern Approach to RPC 259 Choosing a Flavor of RPC 263 REST 264 Demystifying REST 264 Resources 264 Hypermedia 265 Statelessness 265 REST Fully Embraces HTTP 266 What REST Is Not 267 REST for Bounded Context Integration 268 Designing for REST 268 Building Event
Driven REST Systems with ASP.NET Web API 273 Maintaining REST Applications 303 Versioning 303 Monitoring and Metrics 303 Drawbacks with REST for Bounded Context Integration 304 Less Fault Tolerance Out of the Box 304 Eventual Consistency 304 The Salient Points 305 PART III: TACTICAL PATTERNS: CREATING EFFECTIVE DOMAIN MODELS CHAPTER 14: INTRODUCING THE DOMAIN MODELING BUILDING BLOCKS 309 Tactical Patterns 310 Patterns to Model Your Domain 310 Entities 310 Value Objects 314 Domain Services 317 Modules 318 Lifecycle Patterns 318 Aggregates 318 Factories 322 Repositories 323 Emerging Patterns 324 Domain Events 324 Event Sourcing 326 The Salient Points 327 CHAPTER 15: VALUE OBJECTS 329 When to Use a Value Object 330 Representing a Descriptive, Identity
Less Concept 330 Enhancing Explicitness 331 Defining Characteristics 333 Identity
Less 333 Attribute
Based Equality 333 Behavior
Rich 337 Cohesive 337 Immutable 337 Combinable 339 Self
Validating 341 Testable 344 Common Modeling Patterns 345 Static Factory Methods 345 Micro Types (Also Known as Tiny Types) 347 Collection Aversion 349 Persistence 35 NoSQL 352 SQL 353 Flat Denormalization 353 Normalizing into Separate Tables 357 The Salient Points 359 CHAPTER 16: ENTITIES 36 Understanding Entities 362 Domain Concepts with Identity and Continuity 362 Context
Dependent 363 Implementing Entities 363 Assigning Identifiers 363 Natural Keys 363 Arbitrarily Generated IDs 364 Datastore
Generated IDs 368 Pushing Behavior into Value Objects and Domain Services 369 Validating and Enforcing Invariants 371 Focusing on Behavior, Not Data 374 Avoiding the "Model the Real
World" Fallacy 377 Designing for Distribution 378 Common Entity Modeling Principles and Patterns 380 Implementing Validation and Invariants with Specifications 380 Avoid the State Pattern; Use Explicit Modeling 382 Avoiding Getters and Setters with the Memento Pattern 385 Favor Hidden
Side
Effect
Free Functions 386 The Salient Points 388 CHAPTER 17: DOMAIN SERVICES 389 Understanding Domain Services 390 When to Use a Domain Service 390 Encapsulating Business Policies and Processes 390 Representing Contracts 394 Anatomy of a Domain Service 395 Avoiding Anemic Domain Models 395 Contrasting with Application Services 396 Utilizing Domain Services 397 In the Service Layer 397 In the Domain 398 Manually Wiring Up 399 Using Dependency Injection 400 Using a Service Locator 400 Applying Double Dispatch 401 Decoupling with Domain Events 402 Should Entities Even Know About Domain Services? 403 The Salient Points 403 CHAPTER 18: DOMAIN EVENTS 405 Essence of the Domain Events Pattern 406 Important Domain Occurrences That Have Already Happened 406 Reacting to Events 407 Optional Asynchrony 407 Internal vs External Events 408 Event Handling Actions 409 Invoke Domain Logic 409 Invoke Application Logic 410 Domain Events' Implementation Patterns 410 Use the .Net Framework's Events Model 410 Use an In
Memory Bus 412 Udi Dahan's Static DomainEvents Class 415 Handling Threading Issues 417 Avoid a Static Class by Using Method Injection 418 Return Domain Events 419 Use an IoC Container as an Event Dispatcher 421 Testing Domain Events 422 Unit Testing 422 Application Service Layer Testing 424 The Salient Points 425 CHAPTER 19: AGGREGATES 427 Managing Complex Object Graphs 428 Favoring a Single Traversal Direction 428 Qualifying Associations 430 Preferring IDs Over Object References 431 Aggregates 434 Design Around Domain Invariants 435 Higher Level of Domain Abstraction 435 Consistency Boundaries 435 Transactional Consistency Internally 436 Eventual Consistency Externally 439 Special Cases 440 Favor Smaller Aggregates 441 Large Aggregates Can Degrade Performance 441 Large Aggregates Are More Susceptible to Concurrency Conflicts 442 Large Aggregates May Not Scale Well 442 Defining Aggregate Boundaries 442 eBidder: The Online Auction Case Study 443 Aligning with Invariants 444 Aligning with Transactions and Consistency 446 Ignoring User Interface Influences 448 Avoiding Dumb Collections and Containers 448 Don't Focus on HAS
A Relationships 449 Refactoring to Aggregates 449 Satisfying Business Use Cases-Not Real Life 449 Implementing Aggregates 450 Selecting an Aggregate Root 450 Exposing Behavioral Interfaces 452 Protecting Internal State 453 Allowing Only Roots to Have Global Identity 454 Referencing Other Aggregates 454 Nothing Outside An Aggregate's Boundary May Hold a Reference to Anything Inside 455 The Aggregate Root Can Hand Out Transient References to the Internal Domain Objects 456 Objects within the Aggregate Can Hold References to Other Aggregate Roots 456 Implementing Persistence 458 Access to Domain Objects for Reading Can Be at the Database Level 460 A Delete Operation Must Remove Everything within the Aggregate Boundary at Once 461 Avoiding Lazy Loading 461 Implementing Transactional Consistency 462 Implementing Eventual Consistency 463 Rules That Span Multiple Aggregates 463 Asynchronous Eventual Consistency 464 Implementing Concurrency 465 The Salient Points 468 CHAPTER 20: FACTORIES 469 The Role of a Factory 469 Separating Use from Construction 470 Encapsulating Internals 470 Hiding Decisions on Creation Type 472 Factory Methods on Aggregates 474 Factories for Reconstitution 475 Use Factories Pragmatically 477 The Salient Points 477 CHAPTER 21: REPOSITORIES 479 Repositories 479 A Misunderstood Pattern 481 Is the Repository an Antipattern? 481 The Difference between a Domain Model and a Persistence Model 482 The Generic Repository 483 Aggregate Persistence Strategies 486 Using a Persistence Framework That Can Map the Domain Model to the Data Model without Compromise 486 Using a Persistence Framework That Cannot Map the Domain Model Directly without Compromise 487 Public Getters and Setters 487 Using the Memento Pattern 488 Event Streams 49 Be Pragmatic 491 A Repository Is an Explicit Contract 492 Transaction Management and Units of Work 493 To Save or Not To Save 497 Persistence Frameworks That Track Domain Object Changes 497 Having to Explicitly Save Changes to Aggregates 498 The Repository as an Anticorruption Layer 499 Other Responsibilities of a Repository 500 Entity ID Generation 500 Collection Summaries 502 Concurrency 503 Audit Trails 506 Repository Antipatterns 506 Antipatterns: Don't Support Ad Hoc Queries 506 Antipatterns: Lazy Loading Is Design Smell 507 Antipatterns: Don't Use Repositories for Reporting Needs 507 Repository Implementations 508 Persistence Framework Can Map Domain Model to Data Model without Compromise 509 NHibernate Example 509 RavenDB Example 543 Persistence Framework Cannot Map Domain Model Directly without Compromise 557 Entity Framework Example 558 Micro ORM Example 577 The Salient Points 593 CHAPTER 22: EVENT SOURCING 595 The Limitations of Storing State as a Snapshot 596 Gaining Competitive Advantage by Storing State as a Stream of Events 597 Temporal Queries 597 Projections 599 Snapshots 599 Event
Sourced Aggregates 600 Structuring 600 Adding Event
Sourcing Capabilities 601 Exposing Expressive Domain
Focused APIs 602 Adding Snapshot Support 604 Persisting and Rehydrating 605 Creating an Event-Sourcing Repository 605 Adding Snapshot Persistence and Reloading 607 Handling Concurrency 609 Testing 610 Building an Event Store 611 Designing a Storage Format 612 Creating Event Streams 614 Appending to Event Streams 614 Querying Event Streams 615 Adding Snapshot Support 616 Managing Concurrency 618 A SQL Server
Based Event Store 621 Choosing a Schema 621 Creating a Stream 622 Saving Events 623 Loading Events from a Stream 624 Snapshots 625 Is Building Your Own Event Store a Good Idea? 627 Using the Purpose
Built Event Store 627 Installing Greg Young's Event Store 628 Using the C# Client Library 627 Running Temporal Queries 632 Querying a Single Stream 632 Querying Multiple Streams 634 Creating Projections 635 CQRS with Event Sourcing 637 Using Projections to Create View Caches 638 CQRS and Event Sourcing Synergy 638 Event Streams as Queues 639 No TwöPhase Commits 639 Recapping the Benefits of Event Sourcing 639 Competitive Business Advantage 639 Expressive Behavior
Focused Aggregates 639 Simplified Persistence 640 Superior Debugging 640 Weighing the Costs of Event Sourcing 640 Versioning 640 New Concepts to Learn and Skills to Hone 640 New Technologies to Learn and Master 641 Greater Data Storage Requirements 641 Additional Learning Resources 641 The Salient Points 641 PART IV: DESIGN PATTERNS FOR EFFECTIVE APPLICATIONS CHAPTER 23: ARCHITECTING APPLICATION USER INTERFACES 645 Design Considerations 646 Owned UIs versus Composed UIs 646 Autonomous 646 Authoritative 647 Some Help Deciding 648 HTML APIs versus Data APIs 649 Client versus Server
Side Aggregation/Coordination 649 Example 1: An HTML API
Based, Server
Side UI for Nondistributed Bounded Contexts 651 Example 2: A Data API
Based, Client
Side UI for Distributed Bounded Contexts 658 The Salient Points 667 CHAPTER 24: CQRS: AN ARCHITECTURE OF A BOUNDED CONTEXT 669 The Challenges of Maintaining a Single Model for Two Contexts 670 A Better Architecture for Complex Bounded Contexts 670 The Command Side: Business Tasks 672 Explicitly Modeling Intent 672 A Model Free from Presentational Distractions 674 Handling a Business Request 675 The Query Side: Domain Reporting 676 Reports Mapped Directly to the Data Model 676 Materialized Views Built from Domain Events 678 The Misconceptions of CQRS 679 CQRS Is Hard 679 CQRS Is Eventually Consistent 679 Your Models Need to Be Event Sourced 680 Commands Should Be Asynchronous 680 CQRS Only Works with Messaging Systems 680 You Need to Use Do
INTRODUCTION xxxv
PART I: THE PRINCIPLES AND PRACTICES OF DOMAIN‐DRIVEN DESIGN
CHAPTER 1: WHAT IS DOMAIN‐DRIVEN DESIGN? 3
The Challenges of Creating Software for Complex Problem Domains 4
Code Created Without a Common Language 4
A Lack of Organization 5
The Ball of Mud Pattern Stifles Development 5
A Lack of Focus on the Problem Domain 6
How the Patterns of Domain‐Driven Design Manage Complexity 6
The Strategic Patterns of DDD 6
Distilling the Problem Domain to Reveal What Is Important 7
Creating a Model to Solve Domain Problems 7
Using a Shared Language to Enable Modeling Collaboration 7
Isolate Models from Ambiguity and Corruption 8
Understanding the Relationships between Contexts 9
The Tactical Patterns of DDD 9
The Problem Space and the Solution Space 9
The Practices and Principles of Domain‐Driven Design 11
Focusing on the Core Domain 11
Learning through Collaboration 11
Creating Models through Exploration and Experimentation 11
Communication 11
Understanding the Applicability of a Model 12
Constantly Evolving the Model 12
Popular Misconceptions of Domain‐Driven Design 12
Tactical Patterns Are Key to DDD 12
DDD Is a Framework 13
DDD Is a Silver Bullet 13
The Salient Points 13
CHAPTER 2: DISTILLING THE PROBLEM DOMAIN 15
Knowledge Crunching and Collaboration 15
Reaching a Shared Understanding through a Shared Language 16
The Importance of Domain Knowledge 17
The Role of Business Analysts 17
An Ongoing Process 17
Gaining Domain Insight with Domain Experts 18
Domain Experts vs Stakeholders 18
Deeper Understanding for the Business 19
Engaging with Your Domain Experts 19
Patterns for Effective Knowledge Crunching 19
Focus on the Most Interesting Conversations 19
Start from the Use Cases 20
Ask Powerful Questions 20
Sketching 20
Class Responsibility Collaboration Cards 21
Defer the Naming of Concepts in Your Model 21
Behavior‐Driven Development 22
Rapid Prototyping 23
Look at Paper‐Based Systems 24
Look For Existing Models 24
Understanding Intent 24
Event Storming 25
Impact Mapping 25
Understanding the Business Model 27
Deliberate Discovery 28
Model Exploration Whirlpool 29
The Salient Points 29
CHAPTER 3: FOCUSING ON THE CORE DOMAIN 31
Why Decompose a Problem Domain? 31
How to Capture the Essence of the Problem 32
Look Beyond Requirements 32
Capture the Domain Vision for a Shared Understanding of What Is Core 32
How to Focus on the Core Problem 33
Distilling a Problem Domain 34
Core Domains 35
Treat Your Core Domain as a Product Rather than a Project 36
Generic Domains 37
Supporting Domains 37
How Subdomains Shape a Solution 37
Not All Parts of a System will be Well Designed 37
Focus on Clean Boundaries over Perfect Models 38
The Core Domain Doesn’t Always Have to Be Perfect the First Time 39
Build Subdomains for Replacement Rather than Reuse 39
What if You Have no Core Domain? 39
The Salient Points 40
CHAPTER 4: MODEL‐DRIVEN DESIGN 41
What Is a Domain Model? 42
The Domain versus the Domain Model 42
The Analysis Model 43
The Code Model 43
The Code Model Is the Primary Expression of the Domain Model 44
Model‐Driven Design 44
The Challenges with Upfront Design 44
Team Modeling 45
Using a Ubiquitous Language to Bind the Analysis to the Code Model 47
A Language Will Outlive Your Software 47
The Language of the Business 48
Translation between the Developers and the Business 48
Collaborating on a Ubiquitous Language 48
Carving Out a Language by Working with Concrete Examples 49
Teach Your Domain Experts to Focus on the Problem and Not Jump to a Solution 50
Best Practices for Shaping the Language 51
How to Create Effective Domain Models 52
Don’t Let the Truth Get in the Way of a Good Model 52
Model Only What Is Relevant 54
Domain Models Are Temporarily Useful 54
Be Explicit with Terminology 54
Limit Your Abstractions 54
Focus Your Code at the Right Level of Abstraction 55
Abstract Behavior Not Implementations 55
Implement the Model in Code Early and Often 56
Don’t Stop at the First Good Idea 56
When to Apply Model‐Driven Design 56
If It’s Not Worth the Effort Don’t Try and Model It 56
Focus on the Core Domain 57
The Salient Points 57
CHAPTER 5: DOMAIN MODEL IMPLEMENTATION PATTERNS 59
The Domain Layer 60
Domain Model Implementation Patterns 60
Domain Model 62
Transaction Script 65
Table Module 67
Active Record 67
Anemic Domain Model 67
Anemic Domain Model and Functional Programming 68
The Salient Points 71
CHAPTER 6: MAINTAINING THE INTEGRITY OF DOMAIN MODELS WITH BOUNDED CONTEXTS 73
The Challenges of a Single Model 74
A Model Can Grow in Complexity 74
Multiple Teams Working on a Single Model 74
Ambiguity in the Language of the Model 75
The Applicability of a Domain Concept 76
Integration with Legacy Code or Third Party Code 78
Your Domain Model Is not Your Enterprise Model 79
Use Bounded Contexts to Divide and Conquer a Large Model 79
Defining a Model’s Boundary 82
Define Boundaries around Language 82
Align to Business Capabilities 83
Create Contexts around Teams 83
Try to Retain Some Communication between Teams 84
Context Game 85
The Difference between a Subdomain and a Bounded Context 85
Implementing Bounded Contexts 85
The Salient Points 89
CHAPTER 7: CONTEXT MAPPING 91
A Reality Map 92
The Technical Reality 92
The Organizational Reality 93
Mapping a Relevant Reality 94
X Marks the Spot of the Core Domain 94
Recognising the Relationships between Bounded Contexts 95
Anticorruption Layer 95
Shared Kernel 96
Open Host Service 97
Separate Ways 97
Partnership 98
An Upstream/Downstream Relationship 98
Customer‐Supplier 99
Conformist 100
Communicating the Context Map 100
The Strategic Importance of Context Maps 101
Retaining Integrity 101
The Basis for a Plan of Attack 101
Understanding Ownership and Responsibility 101
Revealing Areas of Confusion in Business Work Flow 102
Identifying Nontechnical Obstacles 102
Encourages Good Communication 102
Helps On‐Board New Starters 102
The Salient Points 103
CHAPTER 8: APPLICATION ARCHITECTURE 105
Application Architecture 105
Separating the Concerns of Your Application 106
Abstraction from the Complexities of the Domain 106
A Layered Architecture 106
Dependency Inversion 107
The Domain Layer 107
The Application Service Layer 108
The Infrastructural Layers 108
Communication Across Layers 108
Testing in Isolation 109
Don t Share Data Schema between Bounded Contexts 109
Application Architectures versus Architectures for Bounded Contexts 111
Application Services 112
Application Logic versus Domain Logic 114
Defining and Exposing Capabilities 114
Business Use Case Coordination 115
Application Services Represent Use Cases, Not Create, Read, Update, and Delete 115
Domain Layer As an Implementation Detail 115
Domain Reporting 116
Read Models versus Transactional Models 116
Application Clients 117
The Salient Points 120
CHAPTER 9: COMMON PROBLEMS FOR TEAMS STARTING OUT WITH DOMAIN‐DRIVEN DESIGN 121
Overemphasizing the Importance of Tactical Patterns 122
Using the Same Architecture for All Bounded Contexts 122
Striving for Tactical Pattern Perfection 122
Mistaking the Building Blocks for the Value of DDD 123
Focusing on Code Rather Than the Principles of DDD 123
Missing the Real Value of DDD: Collaboration, Communication, and Context 124
Producing a Big Ball of Mud Due to Underestimating the Importance of Context 124
Causing Ambiguity and Misinterpretations by Failing to Create a UL 125
Designing Technical‐Focused Solutions Due to a Lack of Collaboration 125
Spending Too Much Time on What’s Not Important 126
Making Simple Problems Complex 126
Applying DDD Principles to a Trivial Domain with Little Business Expectation 126
Disregarding CRUD as an Antipattern 127
Using the Domain Model Pattern for Every Bounded Context 127
Ask Yourself: Is It Worth This Extra Complexity? 127
Underestimating the Cost of Applying DDD 127
Trying to Succeed Without a Motivated and Focused Team 128
Attempting Collaboration When a Domain Expert Is Not Behind the Project 128
Learning in a Noniterative Development Methodology 128
Applying DDD to Every Problem 129
Sacrificing Pragmatism for Needless Purity 129
Wasted Effort by Seeking Validation 129
Always Striving for Beautiful Code 130
DDD Is About Providing Value 130
The Salient Points 130
CHAPTER 10: APPLYING THE PRINCIPLES, PRACTICES, AND PATTERNS OF DDD 131
Selling DDD 132
Educating Your Team 132
Speaking to Your Business 132
Applying the Principles of DDD 133
Understand the Vision 133
Capture the Required Behaviors 134
Distilling the Problem Space 134
Focus on What Is Important 134
Understand the Reality of the Landscape 135
Modeling a Solution 135
All Problems Are Not Created Equal 136
Engaging with an Expert 136
Select a Behavior and Model Around a Concrete Scenario 137
Collaborate with the Domain Expert on the Most Interesting Parts 137
Evolve UL to Remove Ambiguity 138
Throw Away Your First Model, and Your Second 138
Implement the Model in Code 139
Creating a Domain Model 139
Keep the Solution Simple and Your Code Boring 139
Carve Out an Area of Safety 140
Integrate the Model Early and Often 140
Nontechnical Refactoring 140
Decompose Your Solution Space 140
Rinse and Repeat 141
Exploration and Experimentation 142
Challenge Your Assumptions 142
Modeling Is a Continuous Activity 142
There Are No Wrong Models 142
Supple Code Aids Discovery 143
Making the Implicit Explicit 143
Tackling Ambiguity 144
Give Things a Name 145
A Problem Solver First, A Technologist Second 146
Don’t Solve All the Problems 146
How Do I Know That I Am Doing It Right? 146
Good Is Good Enough 147
Practice, Practice, Practice 147
The Salient Points 147
PART II: STRATEGIC PATTERNS: COMMUNICATING BETWEEN BOUNDED CONTEXTS
CHAPTER 11: INTRODUCTION TO BOUNDED CONTEXT INTEGRATION 151
How to Integrate Bounded Contexts 152
Bounded Contexts Are Autonomous 153
The Challenges of Integrating Bounded Contexts at the Code Level 153
Multiple Bounded Contexts Exist within a Solution 153
Namespaces or Projects to Keep Bounded Contexts Separate 154
Integrating via the Database 155
Multiple Teams Working in a Single Codebase 156
Models Blur 156
Use Physical Boundaries to Enforce Clean Models 157
Integrating with Legacy Systems 158
Bubble Context 158
Autonomous Bubble Context 158
Exposing Legacy Systems as Services 160
Integrating Distributed Bounded Contexts 161
Integration Strategies for Distributed Bounded Contexts 161
Database Integration 162
Flat File Integration 163
RPC 164
Messaging 165
REST 165
The Challenges of DDD with Distributed Systems 165
The Problem with RPC 166
RPC Is Harder to Make Resilient 167
RPC Costs More to Scale 167
RPC Involves Tight Coupling 168
Distributed Transactions Hurt Scalability and Reliability 169
Bounded Contexts Don’t Have to Be Consistent with Each Other 169
Eventual Consistency 169
Event‐Driven Reactive DDD 170
Demonstrating the Resilience and Scalability of Reactive Solutions 171
Challenges and Trade‐Offs of Asynchronous Messaging 173
Is RPC Still Relevant? 173
SOA and Reactive DDD 174
View Your Bounded Contexts as SOA Services 175
Decompose Bounded Contexts into Business Components 175
Decompose Business Components into Components 176
Going Even Further with Micro Service Architecture 178
The Salient Points 180
CHAPTER 12: INTEGRATING VIA MESSAGING 181
Messaging Fundamentals 182
Message Bus 182
Reliable Messaging 184
Store‐and‐Forward 184
Commands and Events 185
Eventual Consistency 186
Building an E‐Commerce Application with NServiceBus 186
Designing the System 187
Domain‐Driven Design 187
Containers Diagrams 188
Evolutionary Architecture 191
Sending Commands from a Web Application 192
Creating a Web Application to Send Messages with NServiceBus 192
Sending Commands 197
Handling Commands and Publishing Events 200
Creating an NServiceBus Server to Handle Commands 200
Configuring the Solution for Testing and Debugging 201
Publishing Events 204
Subscribing to Events 206
Making External HTTP Calls Reliable with Messaging Gateways 208
Messaging Gateways Improve Fault Tolerance 208
Implementing a Messaging Gateway 209
Controlling Message Retries 212
Eventual Consistency in Practice 215
Dealing with Inconsistency 215
Rolling Forward into New States 215
Bounded Contexts Store All the Data They Need Locally 216
Storage Is Cheap—Keep a Local Copy 217
Common Data Duplication Concerns 223
Pulling It All Together in the UI 224
Business Components Need Their Own APIs 225
Be Wary of Server‐Side Orchestration 226
UI Composition with AJAX Data 226
UI Composition with AJAX HTML 226
Sharing Your APIs with the Outside World 227
Maintaining a Messaging Application 227
Message Versioning 228
Backward‐Compatible Message Versioning 228
Handling Versioning with NServiceBus’s Polymorphic Handlers 229
Monitoring and Scaling 233
Monitoring Errors 233
Monitoring SLAs 234
Scaling Out 235
Integrating a Bounded Context with Mass Transit 235
Messaging Bridge 236
Mass Transit 236
Installing and Configuring Mass Transit 236
Declaring Messages for Use by Mass Transit 238
Creating a Message Handler 239
Subscribing to Events 239
Linking the Systems with a Messaging Bridge 240
Publishing Events 242
Testing It Out 243
Where to Learn More about Mass Transit 243
The Salient Points 243
CHAPTER 13: INTEGRATING VIA HTTP WITH RPC AND REST 245
Why Prefer HTTP? 247
No Platform Coupling 247
Everyone Understands HTTP 247
Lots of Mature Tooling and Libraries 247
Dogfooding Your APIs 247
RPC 248
Implementing RPC over HTTP 248
SOAP 249
Plain XML or JSON: The Modern Approach to RPC 259
Choosing a Flavor of RPC 263
REST 264
Demystifying REST 264
Resources 264
Hypermedia 265
Statelessness 265
REST Fully Embraces HTTP 266
What REST Is Not 267
REST for Bounded Context Integration 268
Designing for REST 268
Building Event‐Driven REST Systems with ASP.NET Web API 273
Maintaining REST Applications 303
Versioning 303
Monitoring and Metrics 303
Drawbacks with REST for Bounded Context Integration 304
Less Fault Tolerance Out of the Box 304
Eventual Consistency 304
The Salient Points 305
PART III: TACTICAL PATTERNS: CREATING EFFECTIVE DOMAIN MODELS
CHAPTER 14: INTRODUCING THE DOMAIN MODELING BUILDING BLOCKS 309
Tactical Patterns 310
Patterns to Model Your Domain 310
Entities 310
Value Objects 314
Domain Services 317
Modules 318
Lifecycle Patterns 318
Aggregates 318
Factories 322
Repositories 323
Emerging Patterns 324
Domain Events 324
Event Sourcing 326
The Salient Points 327
CHAPTER 15: VALUE OBJECTS 329
When to Use a Value Object 330
Representing a Descriptive, Identity‐Less Concept 330
Enhancing Explicitness 331
Defining Characteristics 333
Identity‐Less 333
Attribute‐Based Equality 333
Behavior‐Rich 337
Cohesive 337
Immutable 337
Combinable 339
Self‐Validating 341
Testable 344
Common Modeling Patterns 345
Static Factory Methods 345
Micro Types (Also Known as Tiny Types) 347
Collection Aversion 349
Persistence 35
NoSQL 352
SQL 353
Flat Denormalization 353
Normalizing into Separate Tables 357
The Salient Points 359
CHAPTER 16: ENTITIES 36
Understanding Entities 362
Domain Concepts with Identity and Continuity 362
Context‐Dependent 363
Implementing Entities 363
Assigning Identifiers 363
Natural Keys 363
Arbitrarily Generated IDs 364
Datastore‐Generated IDs 368
Pushing Behavior into Value Objects and Domain Services 369
Validating and Enforcing Invariants 371
Focusing on Behavior, Not Data 374
Avoiding the “Model the Real‐World” Fallacy 377
Designing for Distribution 378
Common Entity Modeling Principles and Patterns 380
Implementing Validation and Invariants with Specifications 380
Avoid the State Pattern; Use Explicit Modeling 382
Avoiding Getters and Setters with the Memento Pattern 385
Favor Hidden‐Side‐Effect‐Free Functions 386
The Salient Points 388
CHAPTER 17: DOMAIN SERVICES 389
Understanding Domain Services 390
When to Use a Domain Service 390
Encapsulating Business Policies and Processes 390
Representing Contracts 394
Anatomy of a Domain Service 395
Avoiding Anemic Domain Models 395
Contrasting with Application Services 396
Utilizing Domain Services 397
In the Service Layer 397
In the Domain 398
Manually Wiring Up 399
Using Dependency Injection 400
Using a Service Locator 400
Applying Double Dispatch 401
Decoupling with Domain Events 402
Should Entities Even Know About Domain Services? 403
The Salient Points 403
CHAPTER 18: DOMAIN EVENTS 405
Essence of the Domain Events Pattern 406
Important Domain Occurrences That Have Already Happened 406
Reacting to Events 407
Optional Asynchrony 407
Internal vs External Events 408
Event Handling Actions 409
Invoke Domain Logic 409
Invoke Application Logic 410
Domain Events’ Implementation Patterns 410
Use the .Net Framework’s Events Model 410
Use an In‐Memory Bus 412
Udi Dahan’s Static DomainEvents Class 415
Handling Threading Issues 417
Avoid a Static Class by Using Method Injection 418
Return Domain Events 419
Use an IoC Container as an Event Dispatcher 421
Testing Domain Events 422
Unit Testing 422
Application Service Layer Testing 424
The Salient Points 425
CHAPTER 19: AGGREGATES 427
Managing Complex Object Graphs 428
Favoring a Single Traversal Direction 428
Qualifying Associations 430
Preferring IDs Over Object References 431
Aggregates 434
Design Around Domain Invariants 435
Higher Level of Domain Abstraction 435
Consistency Boundaries 435
Transactional Consistency Internally 436
Eventual Consistency Externally 439
Special Cases 440
Favor Smaller Aggregates 441
Large Aggregates Can Degrade Performance 441
Large Aggregates Are More Susceptible to Concurrency Conflicts 442
Large Aggregates May Not Scale Well 442
Defining Aggregate Boundaries 442
eBidder: The Online Auction Case Study 443
Aligning with Invariants 444
Aligning with Transactions and Consistency 446
Ignoring User Interface Influences 448
Avoiding Dumb Collections and Containers 448
Don’t Focus on HAS‐A Relationships 449
Refactoring to Aggregates 449
Satisfying Business Use Cases—Not Real Life 449
Implementing Aggregates 450
Selecting an Aggregate Root 450
Exposing Behavioral Interfaces 452
Protecting Internal State 453
Allowing Only Roots to Have Global Identity 454
Referencing Other Aggregates 454
Nothing Outside An Aggregate’s Boundary May Hold a Reference to Anything Inside 455
The Aggregate Root Can Hand Out Transient References to the Internal Domain Objects 456
Objects within the Aggregate Can Hold References to Other Aggregate Roots 456
Implementing Persistence 458
Access to Domain Objects for Reading Can Be at the Database Level 460
A Delete Operation Must Remove Everything within the Aggregate Boundary at Once 461
Avoiding Lazy Loading 461
Implementing Transactional Consistency 462
Implementing Eventual Consistency 463
Rules That Span Multiple Aggregates 463
Asynchronous Eventual Consistency 464
Implementing Concurrency 465
The Salient Points 468
CHAPTER 20: FACTORIES 469
The Role of a Factory 469
Separating Use from Construction 470
Encapsulating Internals 470
Hiding Decisions on Creation Type 472
Factory Methods on Aggregates 474
Factories for Reconstitution 475
Use Factories Pragmatically 477
The Salient Points 477
CHAPTER 21: REPOSITORIES 479
Repositories 479
A Misunderstood Pattern 481
Is the Repository an Antipattern? 481
The Difference between a Domain Model and a Persistence Model 482
The Generic Repository 483
Aggregate Persistence Strategies 486
Using a Persistence Framework That Can Map the Domain Model to the Data Model without Compromise 486
Using a Persistence Framework That Cannot Map the Domain Model Directly without Compromise 487
Public Getters and Setters 487
Using the Memento Pattern 488
Event Streams 49
Be Pragmatic 491
A Repository Is an Explicit Contract 492
Transaction Management and Units of Work 493
To Save or Not To Save 497
Persistence Frameworks That Track Domain Object Changes 497
Having to Explicitly Save Changes to Aggregates 498
The Repository as an Anticorruption Layer 499
Other Responsibilities of a Repository 500
Entity ID Generation 500
Collection Summaries 502
Concurrency 503
Audit Trails 506
Repository Antipatterns 506
Antipatterns: Don’t Support Ad Hoc Queries 506
Antipatterns: Lazy Loading Is Design Smell 507
Antipatterns: Don’t Use Repositories for Reporting Needs 507
Repository Implementations 508
Persistence Framework Can Map Domain Model to Data Model without Compromise 509
NHibernate Example 509
RavenDB Example 543
Persistence Framework Cannot Map Domain Model Directly without Compromise 557
Entity Framework Example 558
Micro ORM Example 577
The Salient Points 593
CHAPTER 22: EVENT SOURCING 595
The Limitations of Storing State as a Snapshot 596
Gaining Competitive Advantage by Storing State as a Stream of Events 597
Temporal Queries 597
Projections 599
Snapshots 599
Event‐Sourced Aggregates 600
Structuring 600
Adding Event‐Sourcing Capabilities 601
Exposing Expressive Domain‐Focused APIs 602
Adding Snapshot Support 604
Persisting and Rehydrating 605
Creating an Event-Sourcing Repository 605
Adding Snapshot Persistence and Reloading 607
Handling Concurrency 609
Testing 610
Building an Event Store 611
Designing a Storage Format 612
Creating Event Streams 614
Appending to Event Streams 614
Querying Event Streams 615
Adding Snapshot Support 616
Managing Concurrency 618
A SQL Server‐Based Event Store 621
Choosing a Schema 621
Creating a Stream 622
Saving Events 623
Loading Events from a Stream 624
Snapshots 625
Is Building Your Own Event Store a Good Idea? 627
Using the Purpose‐Built Event Store 627
Installing Greg Young’s Event Store 628
Using the C# Client Library 627
Running Temporal Queries 632
Querying a Single Stream 632
Querying Multiple Streams 634
Creating Projections 635
CQRS with Event Sourcing 637
Using Projections to Create View Caches 638
CQRS and Event Sourcing Synergy 638
Event Streams as Queues 639
No Two‐Phase Commits 639
Recapping the Benefits of Event Sourcing 639
Competitive Business Advantage 639
Expressive Behavior‐Focused Aggregates 639
Simplified Persistence 640
Superior Debugging 640
Weighing the Costs of Event Sourcing 640
Versioning 640
New Concepts to Learn and Skills to Hone 640
New Technologies to Learn and Master 641
Greater Data Storage Requirements 641
Additional Learning Resources 641
The Salient Points 641
PART IV: DESIGN PATTERNS FOR EFFECTIVE APPLICATIONS
CHAPTER 23: ARCHITECTING APPLICATION USER INTERFACES 645
Design Considerations 646
Owned UIs versus Composed UIs 646
Autonomous 646
Authoritative 647
Some Help Deciding 648
HTML APIs versus Data APIs 649
Client versus Server‐Side Aggregation/Coordination 649
Example 1: An HTML API‐Based, Server‐Side UI for Nondistributed Bounded Contexts 651
Example 2: A Data API‐Based, Client‐Side UI for Distributed Bounded Contexts 658
The Salient Points 667
CHAPTER 24: CQRS: AN ARCHITECTURE OF A BOUNDED CONTEXT 669
The Challenges of Maintaining a Single Model for Two Contexts 670
A Better Architecture for Complex Bounded Contexts 670
The Command Side: Business Tasks 672
Explicitly Modeling Intent 672
A Model Free from Presentational Distractions 674
Handling a Business Request 675
The Query Side: Domain Reporting 676
Reports Mapped Directly to the Data Model 676
Materialized Views Built from Domain Events 678
The Misconceptions of CQRS 679
CQRS Is Hard 679
CQRS Is Eventually Consistent 679
Your Models Need to Be Event Sourced 680
Commands Should Be Asynchronous 680
CQRS Only Works with Messaging Systems 680
You Need to Use Domain Events with CQRS 680
Patterns to Enable Your Application to Scale 680
Scaling the Read Side: An Eventually Consistent Read Model 681
The Impact to the User Experience 682
Use the Read Model to Consolidate Many Bounded Contexts 682
Using a Reporting Database or a Caching Layer 682
Scaling the Write Side: Using Asynchronous Commands 683
Command Validation 683
Impact to the User Experience 684
Scaling It All 684
The Salient Points 685
CHAPTER 25: COMMANDS: APPLICATION SERVICE PATTERNS FOR PROCESSING BUSINESS USE CASES 687
Differentiating Application Logic and Domain Logic 689
Application Logic 689
Infrastructural Concerns 690
Coordinating Full Business Use Cases 698
Application Services and Framework Integration 698
Domain Logic from an Application Service’s Perspective 700
Application Service Patterns 700
Command Processor 701
Publish/Subscribe 704
Request/Reply Pattern 706
async/await 708
Testing Application Services 709
Use Domain Terminology 709
Test as Much Functionality as Possible 710
The Salient Points 712
CHAPTER 26: QUERIES: DOMAIN REPORTING 713
Domain Reporting within a Bounded Context 714
Deriving Reports from Domain Objects 714
Using Simple Mappings 714
Using the Mediator Pattern 718
Going Directly to the Datastore 720
Querying a Datastore 721
Reading Denormalized View Caches 724
Building Projections from Event Streams 726
Setting Up ES for Projections 727
Creating Reporting Projections 728
Counting the Number of Events in a Stream 729
Creating As Many Streams As Required 729
Building a Report from Streams and Projections 730
Domain Reporting Across Bounded Contexts 733
Composed UI 733
Separate Reporting Context 734
The Salient Points 736
INDEX 737
PART I: THE PRINCIPLES AND PRACTICES OF DOMAIN‐DRIVEN DESIGN
CHAPTER 1: WHAT IS DOMAIN‐DRIVEN DESIGN? 3
The Challenges of Creating Software for Complex Problem Domains 4
Code Created Without a Common Language 4
A Lack of Organization 5
The Ball of Mud Pattern Stifles Development 5
A Lack of Focus on the Problem Domain 6
How the Patterns of Domain‐Driven Design Manage Complexity 6
The Strategic Patterns of DDD 6
Distilling the Problem Domain to Reveal What Is Important 7
Creating a Model to Solve Domain Problems 7
Using a Shared Language to Enable Modeling Collaboration 7
Isolate Models from Ambiguity and Corruption 8
Understanding the Relationships between Contexts 9
The Tactical Patterns of DDD 9
The Problem Space and the Solution Space 9
The Practices and Principles of Domain‐Driven Design 11
Focusing on the Core Domain 11
Learning through Collaboration 11
Creating Models through Exploration and Experimentation 11
Communication 11
Understanding the Applicability of a Model 12
Constantly Evolving the Model 12
Popular Misconceptions of Domain‐Driven Design 12
Tactical Patterns Are Key to DDD 12
DDD Is a Framework 13
DDD Is a Silver Bullet 13
The Salient Points 13
CHAPTER 2: DISTILLING THE PROBLEM DOMAIN 15
Knowledge Crunching and Collaboration 15
Reaching a Shared Understanding through a Shared Language 16
The Importance of Domain Knowledge 17
The Role of Business Analysts 17
An Ongoing Process 17
Gaining Domain Insight with Domain Experts 18
Domain Experts vs Stakeholders 18
Deeper Understanding for the Business 19
Engaging with Your Domain Experts 19
Patterns for Effective Knowledge Crunching 19
Focus on the Most Interesting Conversations 19
Start from the Use Cases 20
Ask Powerful Questions 20
Sketching 20
Class Responsibility Collaboration Cards 21
Defer the Naming of Concepts in Your Model 21
Behavior‐Driven Development 22
Rapid Prototyping 23
Look at Paper‐Based Systems 24
Look For Existing Models 24
Understanding Intent 24
Event Storming 25
Impact Mapping 25
Understanding the Business Model 27
Deliberate Discovery 28
Model Exploration Whirlpool 29
The Salient Points 29
CHAPTER 3: FOCUSING ON THE CORE DOMAIN 31
Why Decompose a Problem Domain? 31
How to Capture the Essence of the Problem 32
Look Beyond Requirements 32
Capture the Domain Vision for a Shared Understanding of What Is Core 32
How to Focus on the Core Problem 33
Distilling a Problem Domain 34
Core Domains 35
Treat Your Core Domain as a Product Rather than a Project 36
Generic Domains 37
Supporting Domains 37
How Subdomains Shape a Solution 37
Not All Parts of a System will be Well Designed 37
Focus on Clean Boundaries over Perfect Models 38
The Core Domain Doesn’t Always Have to Be Perfect the First Time 39
Build Subdomains for Replacement Rather than Reuse 39
What if You Have no Core Domain? 39
The Salient Points 40
CHAPTER 4: MODEL‐DRIVEN DESIGN 41
What Is a Domain Model? 42
The Domain versus the Domain Model 42
The Analysis Model 43
The Code Model 43
The Code Model Is the Primary Expression of the Domain Model 44
Model‐Driven Design 44
The Challenges with Upfront Design 44
Team Modeling 45
Using a Ubiquitous Language to Bind the Analysis to the Code Model 47
A Language Will Outlive Your Software 47
The Language of the Business 48
Translation between the Developers and the Business 48
Collaborating on a Ubiquitous Language 48
Carving Out a Language by Working with Concrete Examples 49
Teach Your Domain Experts to Focus on the Problem and Not Jump to a Solution 50
Best Practices for Shaping the Language 51
How to Create Effective Domain Models 52
Don’t Let the Truth Get in the Way of a Good Model 52
Model Only What Is Relevant 54
Domain Models Are Temporarily Useful 54
Be Explicit with Terminology 54
Limit Your Abstractions 54
Focus Your Code at the Right Level of Abstraction 55
Abstract Behavior Not Implementations 55
Implement the Model in Code Early and Often 56
Don’t Stop at the First Good Idea 56
When to Apply Model‐Driven Design 56
If It’s Not Worth the Effort Don’t Try and Model It 56
Focus on the Core Domain 57
The Salient Points 57
CHAPTER 5: DOMAIN MODEL IMPLEMENTATION PATTERNS 59
The Domain Layer 60
Domain Model Implementation Patterns 60
Domain Model 62
Transaction Script 65
Table Module 67
Active Record 67
Anemic Domain Model 67
Anemic Domain Model and Functional Programming 68
The Salient Points 71
CHAPTER 6: MAINTAINING THE INTEGRITY OF DOMAIN MODELS WITH BOUNDED CONTEXTS 73
The Challenges of a Single Model 74
A Model Can Grow in Complexity 74
Multiple Teams Working on a Single Model 74
Ambiguity in the Language of the Model 75
The Applicability of a Domain Concept 76
Integration with Legacy Code or Third Party Code 78
Your Domain Model Is not Your Enterprise Model 79
Use Bounded Contexts to Divide and Conquer a Large Model 79
Defining a Model’s Boundary 82
Define Boundaries around Language 82
Align to Business Capabilities 83
Create Contexts around Teams 83
Try to Retain Some Communication between Teams 84
Context Game 85
The Difference between a Subdomain and a Bounded Context 85
Implementing Bounded Contexts 85
The Salient Points 89
CHAPTER 7: CONTEXT MAPPING 91
A Reality Map 92
The Technical Reality 92
The Organizational Reality 93
Mapping a Relevant Reality 94
X Marks the Spot of the Core Domain 94
Recognising the Relationships between Bounded Contexts 95
Anticorruption Layer 95
Shared Kernel 96
Open Host Service 97
Separate Ways 97
Partnership 98
An Upstream/Downstream Relationship 98
Customer‐Supplier 99
Conformist 100
Communicating the Context Map 100
The Strategic Importance of Context Maps 101
Retaining Integrity 101
The Basis for a Plan of Attack 101
Understanding Ownership and Responsibility 101
Revealing Areas of Confusion in Business Work Flow 102
Identifying Nontechnical Obstacles 102
Encourages Good Communication 102
Helps On‐Board New Starters 102
The Salient Points 103
CHAPTER 8: APPLICATION ARCHITECTURE 105
Application Architecture 105
Separating the Concerns of Your Application 106
Abstraction from the Complexities of the Domain 106
A Layered Architecture 106
Dependency Inversion 107
The Domain Layer 107
The Application Service Layer 108
The Infrastructural Layers 108
Communication Across Layers 108
Testing in Isolation 109
Don t Share Data Schema between Bounded Contexts 109
Application Architectures versus Architectures for Bounded Contexts 111
Application Services 112
Application Logic versus Domain Logic 114
Defining and Exposing Capabilities 114
Business Use Case Coordination 115
Application Services Represent Use Cases, Not Create, Read, Update, and Delete 115
Domain Layer As an Implementation Detail 115
Domain Reporting 116
Read Models versus Transactional Models 116
Application Clients 117
The Salient Points 120
CHAPTER 9: COMMON PROBLEMS FOR TEAMS STARTING OUT WITH DOMAIN‐DRIVEN DESIGN 121
Overemphasizing the Importance of Tactical Patterns 122
Using the Same Architecture for All Bounded Contexts 122
Striving for Tactical Pattern Perfection 122
Mistaking the Building Blocks for the Value of DDD 123
Focusing on Code Rather Than the Principles of DDD 123
Missing the Real Value of DDD: Collaboration, Communication, and Context 124
Producing a Big Ball of Mud Due to Underestimating the Importance of Context 124
Causing Ambiguity and Misinterpretations by Failing to Create a UL 125
Designing Technical‐Focused Solutions Due to a Lack of Collaboration 125
Spending Too Much Time on What’s Not Important 126
Making Simple Problems Complex 126
Applying DDD Principles to a Trivial Domain with Little Business Expectation 126
Disregarding CRUD as an Antipattern 127
Using the Domain Model Pattern for Every Bounded Context 127
Ask Yourself: Is It Worth This Extra Complexity? 127
Underestimating the Cost of Applying DDD 127
Trying to Succeed Without a Motivated and Focused Team 128
Attempting Collaboration When a Domain Expert Is Not Behind the Project 128
Learning in a Noniterative Development Methodology 128
Applying DDD to Every Problem 129
Sacrificing Pragmatism for Needless Purity 129
Wasted Effort by Seeking Validation 129
Always Striving for Beautiful Code 130
DDD Is About Providing Value 130
The Salient Points 130
CHAPTER 10: APPLYING THE PRINCIPLES, PRACTICES, AND PATTERNS OF DDD 131
Selling DDD 132
Educating Your Team 132
Speaking to Your Business 132
Applying the Principles of DDD 133
Understand the Vision 133
Capture the Required Behaviors 134
Distilling the Problem Space 134
Focus on What Is Important 134
Understand the Reality of the Landscape 135
Modeling a Solution 135
All Problems Are Not Created Equal 136
Engaging with an Expert 136
Select a Behavior and Model Around a Concrete Scenario 137
Collaborate with the Domain Expert on the Most Interesting Parts 137
Evolve UL to Remove Ambiguity 138
Throw Away Your First Model, and Your Second 138
Implement the Model in Code 139
Creating a Domain Model 139
Keep the Solution Simple and Your Code Boring 139
Carve Out an Area of Safety 140
Integrate the Model Early and Often 140
Nontechnical Refactoring 140
Decompose Your Solution Space 140
Rinse and Repeat 141
Exploration and Experimentation 142
Challenge Your Assumptions 142
Modeling Is a Continuous Activity 142
There Are No Wrong Models 142
Supple Code Aids Discovery 143
Making the Implicit Explicit 143
Tackling Ambiguity 144
Give Things a Name 145
A Problem Solver First, A Technologist Second 146
Don’t Solve All the Problems 146
How Do I Know That I Am Doing It Right? 146
Good Is Good Enough 147
Practice, Practice, Practice 147
The Salient Points 147
PART II: STRATEGIC PATTERNS: COMMUNICATING BETWEEN BOUNDED CONTEXTS
CHAPTER 11: INTRODUCTION TO BOUNDED CONTEXT INTEGRATION 151
How to Integrate Bounded Contexts 152
Bounded Contexts Are Autonomous 153
The Challenges of Integrating Bounded Contexts at the Code Level 153
Multiple Bounded Contexts Exist within a Solution 153
Namespaces or Projects to Keep Bounded Contexts Separate 154
Integrating via the Database 155
Multiple Teams Working in a Single Codebase 156
Models Blur 156
Use Physical Boundaries to Enforce Clean Models 157
Integrating with Legacy Systems 158
Bubble Context 158
Autonomous Bubble Context 158
Exposing Legacy Systems as Services 160
Integrating Distributed Bounded Contexts 161
Integration Strategies for Distributed Bounded Contexts 161
Database Integration 162
Flat File Integration 163
RPC 164
Messaging 165
REST 165
The Challenges of DDD with Distributed Systems 165
The Problem with RPC 166
RPC Is Harder to Make Resilient 167
RPC Costs More to Scale 167
RPC Involves Tight Coupling 168
Distributed Transactions Hurt Scalability and Reliability 169
Bounded Contexts Don’t Have to Be Consistent with Each Other 169
Eventual Consistency 169
Event‐Driven Reactive DDD 170
Demonstrating the Resilience and Scalability of Reactive Solutions 171
Challenges and Trade‐Offs of Asynchronous Messaging 173
Is RPC Still Relevant? 173
SOA and Reactive DDD 174
View Your Bounded Contexts as SOA Services 175
Decompose Bounded Contexts into Business Components 175
Decompose Business Components into Components 176
Going Even Further with Micro Service Architecture 178
The Salient Points 180
CHAPTER 12: INTEGRATING VIA MESSAGING 181
Messaging Fundamentals 182
Message Bus 182
Reliable Messaging 184
Store‐and‐Forward 184
Commands and Events 185
Eventual Consistency 186
Building an E‐Commerce Application with NServiceBus 186
Designing the System 187
Domain‐Driven Design 187
Containers Diagrams 188
Evolutionary Architecture 191
Sending Commands from a Web Application 192
Creating a Web Application to Send Messages with NServiceBus 192
Sending Commands 197
Handling Commands and Publishing Events 200
Creating an NServiceBus Server to Handle Commands 200
Configuring the Solution for Testing and Debugging 201
Publishing Events 204
Subscribing to Events 206
Making External HTTP Calls Reliable with Messaging Gateways 208
Messaging Gateways Improve Fault Tolerance 208
Implementing a Messaging Gateway 209
Controlling Message Retries 212
Eventual Consistency in Practice 215
Dealing with Inconsistency 215
Rolling Forward into New States 215
Bounded Contexts Store All the Data They Need Locally 216
Storage Is Cheap—Keep a Local Copy 217
Common Data Duplication Concerns 223
Pulling It All Together in the UI 224
Business Components Need Their Own APIs 225
Be Wary of Server‐Side Orchestration 226
UI Composition with AJAX Data 226
UI Composition with AJAX HTML 226
Sharing Your APIs with the Outside World 227
Maintaining a Messaging Application 227
Message Versioning 228
Backward‐Compatible Message Versioning 228
Handling Versioning with NServiceBus’s Polymorphic Handlers 229
Monitoring and Scaling 233
Monitoring Errors 233
Monitoring SLAs 234
Scaling Out 235
Integrating a Bounded Context with Mass Transit 235
Messaging Bridge 236
Mass Transit 236
Installing and Configuring Mass Transit 236
Declaring Messages for Use by Mass Transit 238
Creating a Message Handler 239
Subscribing to Events 239
Linking the Systems with a Messaging Bridge 240
Publishing Events 242
Testing It Out 243
Where to Learn More about Mass Transit 243
The Salient Points 243
CHAPTER 13: INTEGRATING VIA HTTP WITH RPC AND REST 245
Why Prefer HTTP? 247
No Platform Coupling 247
Everyone Understands HTTP 247
Lots of Mature Tooling and Libraries 247
Dogfooding Your APIs 247
RPC 248
Implementing RPC over HTTP 248
SOAP 249
Plain XML or JSON: The Modern Approach to RPC 259
Choosing a Flavor of RPC 263
REST 264
Demystifying REST 264
Resources 264
Hypermedia 265
Statelessness 265
REST Fully Embraces HTTP 266
What REST Is Not 267
REST for Bounded Context Integration 268
Designing for REST 268
Building Event‐Driven REST Systems with ASP.NET Web API 273
Maintaining REST Applications 303
Versioning 303
Monitoring and Metrics 303
Drawbacks with REST for Bounded Context Integration 304
Less Fault Tolerance Out of the Box 304
Eventual Consistency 304
The Salient Points 305
PART III: TACTICAL PATTERNS: CREATING EFFECTIVE DOMAIN MODELS
CHAPTER 14: INTRODUCING THE DOMAIN MODELING BUILDING BLOCKS 309
Tactical Patterns 310
Patterns to Model Your Domain 310
Entities 310
Value Objects 314
Domain Services 317
Modules 318
Lifecycle Patterns 318
Aggregates 318
Factories 322
Repositories 323
Emerging Patterns 324
Domain Events 324
Event Sourcing 326
The Salient Points 327
CHAPTER 15: VALUE OBJECTS 329
When to Use a Value Object 330
Representing a Descriptive, Identity‐Less Concept 330
Enhancing Explicitness 331
Defining Characteristics 333
Identity‐Less 333
Attribute‐Based Equality 333
Behavior‐Rich 337
Cohesive 337
Immutable 337
Combinable 339
Self‐Validating 341
Testable 344
Common Modeling Patterns 345
Static Factory Methods 345
Micro Types (Also Known as Tiny Types) 347
Collection Aversion 349
Persistence 35
NoSQL 352
SQL 353
Flat Denormalization 353
Normalizing into Separate Tables 357
The Salient Points 359
CHAPTER 16: ENTITIES 36
Understanding Entities 362
Domain Concepts with Identity and Continuity 362
Context‐Dependent 363
Implementing Entities 363
Assigning Identifiers 363
Natural Keys 363
Arbitrarily Generated IDs 364
Datastore‐Generated IDs 368
Pushing Behavior into Value Objects and Domain Services 369
Validating and Enforcing Invariants 371
Focusing on Behavior, Not Data 374
Avoiding the “Model the Real‐World” Fallacy 377
Designing for Distribution 378
Common Entity Modeling Principles and Patterns 380
Implementing Validation and Invariants with Specifications 380
Avoid the State Pattern; Use Explicit Modeling 382
Avoiding Getters and Setters with the Memento Pattern 385
Favor Hidden‐Side‐Effect‐Free Functions 386
The Salient Points 388
CHAPTER 17: DOMAIN SERVICES 389
Understanding Domain Services 390
When to Use a Domain Service 390
Encapsulating Business Policies and Processes 390
Representing Contracts 394
Anatomy of a Domain Service 395
Avoiding Anemic Domain Models 395
Contrasting with Application Services 396
Utilizing Domain Services 397
In the Service Layer 397
In the Domain 398
Manually Wiring Up 399
Using Dependency Injection 400
Using a Service Locator 400
Applying Double Dispatch 401
Decoupling with Domain Events 402
Should Entities Even Know About Domain Services? 403
The Salient Points 403
CHAPTER 18: DOMAIN EVENTS 405
Essence of the Domain Events Pattern 406
Important Domain Occurrences That Have Already Happened 406
Reacting to Events 407
Optional Asynchrony 407
Internal vs External Events 408
Event Handling Actions 409
Invoke Domain Logic 409
Invoke Application Logic 410
Domain Events’ Implementation Patterns 410
Use the .Net Framework’s Events Model 410
Use an In‐Memory Bus 412
Udi Dahan’s Static DomainEvents Class 415
Handling Threading Issues 417
Avoid a Static Class by Using Method Injection 418
Return Domain Events 419
Use an IoC Container as an Event Dispatcher 421
Testing Domain Events 422
Unit Testing 422
Application Service Layer Testing 424
The Salient Points 425
CHAPTER 19: AGGREGATES 427
Managing Complex Object Graphs 428
Favoring a Single Traversal Direction 428
Qualifying Associations 430
Preferring IDs Over Object References 431
Aggregates 434
Design Around Domain Invariants 435
Higher Level of Domain Abstraction 435
Consistency Boundaries 435
Transactional Consistency Internally 436
Eventual Consistency Externally 439
Special Cases 440
Favor Smaller Aggregates 441
Large Aggregates Can Degrade Performance 441
Large Aggregates Are More Susceptible to Concurrency Conflicts 442
Large Aggregates May Not Scale Well 442
Defining Aggregate Boundaries 442
eBidder: The Online Auction Case Study 443
Aligning with Invariants 444
Aligning with Transactions and Consistency 446
Ignoring User Interface Influences 448
Avoiding Dumb Collections and Containers 448
Don’t Focus on HAS‐A Relationships 449
Refactoring to Aggregates 449
Satisfying Business Use Cases—Not Real Life 449
Implementing Aggregates 450
Selecting an Aggregate Root 450
Exposing Behavioral Interfaces 452
Protecting Internal State 453
Allowing Only Roots to Have Global Identity 454
Referencing Other Aggregates 454
Nothing Outside An Aggregate’s Boundary May Hold a Reference to Anything Inside 455
The Aggregate Root Can Hand Out Transient References to the Internal Domain Objects 456
Objects within the Aggregate Can Hold References to Other Aggregate Roots 456
Implementing Persistence 458
Access to Domain Objects for Reading Can Be at the Database Level 460
A Delete Operation Must Remove Everything within the Aggregate Boundary at Once 461
Avoiding Lazy Loading 461
Implementing Transactional Consistency 462
Implementing Eventual Consistency 463
Rules That Span Multiple Aggregates 463
Asynchronous Eventual Consistency 464
Implementing Concurrency 465
The Salient Points 468
CHAPTER 20: FACTORIES 469
The Role of a Factory 469
Separating Use from Construction 470
Encapsulating Internals 470
Hiding Decisions on Creation Type 472
Factory Methods on Aggregates 474
Factories for Reconstitution 475
Use Factories Pragmatically 477
The Salient Points 477
CHAPTER 21: REPOSITORIES 479
Repositories 479
A Misunderstood Pattern 481
Is the Repository an Antipattern? 481
The Difference between a Domain Model and a Persistence Model 482
The Generic Repository 483
Aggregate Persistence Strategies 486
Using a Persistence Framework That Can Map the Domain Model to the Data Model without Compromise 486
Using a Persistence Framework That Cannot Map the Domain Model Directly without Compromise 487
Public Getters and Setters 487
Using the Memento Pattern 488
Event Streams 49
Be Pragmatic 491
A Repository Is an Explicit Contract 492
Transaction Management and Units of Work 493
To Save or Not To Save 497
Persistence Frameworks That Track Domain Object Changes 497
Having to Explicitly Save Changes to Aggregates 498
The Repository as an Anticorruption Layer 499
Other Responsibilities of a Repository 500
Entity ID Generation 500
Collection Summaries 502
Concurrency 503
Audit Trails 506
Repository Antipatterns 506
Antipatterns: Don’t Support Ad Hoc Queries 506
Antipatterns: Lazy Loading Is Design Smell 507
Antipatterns: Don’t Use Repositories for Reporting Needs 507
Repository Implementations 508
Persistence Framework Can Map Domain Model to Data Model without Compromise 509
NHibernate Example 509
RavenDB Example 543
Persistence Framework Cannot Map Domain Model Directly without Compromise 557
Entity Framework Example 558
Micro ORM Example 577
The Salient Points 593
CHAPTER 22: EVENT SOURCING 595
The Limitations of Storing State as a Snapshot 596
Gaining Competitive Advantage by Storing State as a Stream of Events 597
Temporal Queries 597
Projections 599
Snapshots 599
Event‐Sourced Aggregates 600
Structuring 600
Adding Event‐Sourcing Capabilities 601
Exposing Expressive Domain‐Focused APIs 602
Adding Snapshot Support 604
Persisting and Rehydrating 605
Creating an Event-Sourcing Repository 605
Adding Snapshot Persistence and Reloading 607
Handling Concurrency 609
Testing 610
Building an Event Store 611
Designing a Storage Format 612
Creating Event Streams 614
Appending to Event Streams 614
Querying Event Streams 615
Adding Snapshot Support 616
Managing Concurrency 618
A SQL Server‐Based Event Store 621
Choosing a Schema 621
Creating a Stream 622
Saving Events 623
Loading Events from a Stream 624
Snapshots 625
Is Building Your Own Event Store a Good Idea? 627
Using the Purpose‐Built Event Store 627
Installing Greg Young’s Event Store 628
Using the C# Client Library 627
Running Temporal Queries 632
Querying a Single Stream 632
Querying Multiple Streams 634
Creating Projections 635
CQRS with Event Sourcing 637
Using Projections to Create View Caches 638
CQRS and Event Sourcing Synergy 638
Event Streams as Queues 639
No Two‐Phase Commits 639
Recapping the Benefits of Event Sourcing 639
Competitive Business Advantage 639
Expressive Behavior‐Focused Aggregates 639
Simplified Persistence 640
Superior Debugging 640
Weighing the Costs of Event Sourcing 640
Versioning 640
New Concepts to Learn and Skills to Hone 640
New Technologies to Learn and Master 641
Greater Data Storage Requirements 641
Additional Learning Resources 641
The Salient Points 641
PART IV: DESIGN PATTERNS FOR EFFECTIVE APPLICATIONS
CHAPTER 23: ARCHITECTING APPLICATION USER INTERFACES 645
Design Considerations 646
Owned UIs versus Composed UIs 646
Autonomous 646
Authoritative 647
Some Help Deciding 648
HTML APIs versus Data APIs 649
Client versus Server‐Side Aggregation/Coordination 649
Example 1: An HTML API‐Based, Server‐Side UI for Nondistributed Bounded Contexts 651
Example 2: A Data API‐Based, Client‐Side UI for Distributed Bounded Contexts 658
The Salient Points 667
CHAPTER 24: CQRS: AN ARCHITECTURE OF A BOUNDED CONTEXT 669
The Challenges of Maintaining a Single Model for Two Contexts 670
A Better Architecture for Complex Bounded Contexts 670
The Command Side: Business Tasks 672
Explicitly Modeling Intent 672
A Model Free from Presentational Distractions 674
Handling a Business Request 675
The Query Side: Domain Reporting 676
Reports Mapped Directly to the Data Model 676
Materialized Views Built from Domain Events 678
The Misconceptions of CQRS 679
CQRS Is Hard 679
CQRS Is Eventually Consistent 679
Your Models Need to Be Event Sourced 680
Commands Should Be Asynchronous 680
CQRS Only Works with Messaging Systems 680
You Need to Use Domain Events with CQRS 680
Patterns to Enable Your Application to Scale 680
Scaling the Read Side: An Eventually Consistent Read Model 681
The Impact to the User Experience 682
Use the Read Model to Consolidate Many Bounded Contexts 682
Using a Reporting Database or a Caching Layer 682
Scaling the Write Side: Using Asynchronous Commands 683
Command Validation 683
Impact to the User Experience 684
Scaling It All 684
The Salient Points 685
CHAPTER 25: COMMANDS: APPLICATION SERVICE PATTERNS FOR PROCESSING BUSINESS USE CASES 687
Differentiating Application Logic and Domain Logic 689
Application Logic 689
Infrastructural Concerns 690
Coordinating Full Business Use Cases 698
Application Services and Framework Integration 698
Domain Logic from an Application Service’s Perspective 700
Application Service Patterns 700
Command Processor 701
Publish/Subscribe 704
Request/Reply Pattern 706
async/await 708
Testing Application Services 709
Use Domain Terminology 709
Test as Much Functionality as Possible 710
The Salient Points 712
CHAPTER 26: QUERIES: DOMAIN REPORTING 713
Domain Reporting within a Bounded Context 714
Deriving Reports from Domain Objects 714
Using Simple Mappings 714
Using the Mediator Pattern 718
Going Directly to the Datastore 720
Querying a Datastore 721
Reading Denormalized View Caches 724
Building Projections from Event Streams 726
Setting Up ES for Projections 727
Creating Reporting Projections 728
Counting the Number of Events in a Stream 729
Creating As Many Streams As Required 729
Building a Report from Streams and Projections 730
Domain Reporting Across Bounded Contexts 733
Composed UI 733
Separate Reporting Context 734
The Salient Points 736
INDEX 737
INTRODUCTION xxxv PART I: THE PRINCIPLES AND PRACTICES OF DOMAIN
DRIVEN DESIGN CHAPTER 1: WHAT IS DOMAIN
DRIVEN DESIGN? 3 The Challenges of Creating Software for Complex Problem Domains 4 Code Created Without a Common Language 4 A Lack of Organization 5 The Ball of Mud Pattern Stifles Development 5 A Lack of Focus on the Problem Domain 6 How the Patterns of Domain
Driven Design Manage Complexity 6 The Strategic Patterns of DDD 6 Distilling the Problem Domain to Reveal What Is Important 7 Creating a Model to Solve Domain Problems 7 Using a Shared Language to Enable Modeling Collaboration 7 Isolate Models from Ambiguity and Corruption 8 Understanding the Relationships between Contexts 9 The Tactical Patterns of DDD 9 The Problem Space and the Solution Space 9 The Practices and Principles of Domain
Driven Design 11 Focusing on the Core Domain 11 Learning through Collaboration 11 Creating Models through Exploration and Experimentation 11 Communication 11 Understanding the Applicability of a Model 12 Constantly Evolving the Model 12 Popular Misconceptions of Domain
Driven Design 12 Tactical Patterns Are Key to DDD 12 DDD Is a Framework 13 DDD Is a Silver Bullet 13 The Salient Points 13 CHAPTER 2: DISTILLING THE PROBLEM DOMAIN 15 Knowledge Crunching and Collaboration 15 Reaching a Shared Understanding through a Shared Language 16 The Importance of Domain Knowledge 17 The Role of Business Analysts 17 An Ongoing Process 17 Gaining Domain Insight with Domain Experts 18 Domain Experts vs Stakeholders 18 Deeper Understanding for the Business 19 Engaging with Your Domain Experts 19 Patterns for Effective Knowledge Crunching 19 Focus on the Most Interesting Conversations 19 Start from the Use Cases 20 Ask Powerful Questions 20 Sketching 20 Class Responsibility Collaboration Cards 21 Defer the Naming of Concepts in Your Model 21 Behavior
Driven Development 22 Rapid Prototyping 23 Look at Paper
Based Systems 24 Look For Existing Models 24 Understanding Intent 24 Event Storming 25 Impact Mapping 25 Understanding the Business Model 27 Deliberate Discovery 28 Model Exploration Whirlpool 29 The Salient Points 29 CHAPTER 3: FOCUSING ON THE CORE DOMAIN 31 Why Decompose a Problem Domain? 31 How to Capture the Essence of the Problem 32 Look Beyond Requirements 32 Capture the Domain Vision for a Shared Understanding of What Is Core 32 How to Focus on the Core Problem 33 Distilling a Problem Domain 34 Core Domains 35 Treat Your Core Domain as a Product Rather than a Project 36 Generic Domains 37 Supporting Domains 37 How Subdomains Shape a Solution 37 Not All Parts of a System will be Well Designed 37 Focus on Clean Boundaries over Perfect Models 38 The Core Domain Doesn't Always Have to Be Perfect the First Time 39 Build Subdomains for Replacement Rather than Reuse 39 What if You Have no Core Domain? 39 The Salient Points 40 CHAPTER 4: MODEL
DRIVEN DESIGN 41 What Is a Domain Model? 42 The Domain versus the Domain Model 42 The Analysis Model 43 The Code Model 43 The Code Model Is the Primary Expression of the Domain Model 44 Model
Driven Design 44 The Challenges with Upfront Design 44 Team Modeling 45 Using a Ubiquitous Language to Bind the Analysis to the Code Model 47 A Language Will Outlive Your Software 47 The Language of the Business 48 Translation between the Developers and the Business 48 Collaborating on a Ubiquitous Language 48 Carving Out a Language by Working with Concrete Examples 49 Teach Your Domain Experts to Focus on the Problem and Not Jump to a Solution 50 Best Practices for Shaping the Language 51 How to Create Effective Domain Models 52 Don't Let the Truth Get in the Way of a Good Model 52 Model Only What Is Relevant 54 Domain Models Are Temporarily Useful 54 Be Explicit with Terminology 54 Limit Your Abstractions 54 Focus Your Code at the Right Level of Abstraction 55 Abstract Behavior Not Implementations 55 Implement the Model in Code Early and Often 56 Don't Stop at the First Good Idea 56 When to Apply Model
Driven Design 56 If It's Not Worth the Effort Don't Try and Model It 56 Focus on the Core Domain 57 The Salient Points 57 CHAPTER 5: DOMAIN MODEL IMPLEMENTATION PATTERNS 59 The Domain Layer 60 Domain Model Implementation Patterns 60 Domain Model 62 Transaction Script 65 Table Module 67 Active Record 67 Anemic Domain Model 67 Anemic Domain Model and Functional Programming 68 The Salient Points 71 CHAPTER 6: MAINTAINING THE INTEGRITY OF DOMAIN MODELS WITH BOUNDED CONTEXTS 73 The Challenges of a Single Model 74 A Model Can Grow in Complexity 74 Multiple Teams Working on a Single Model 74 Ambiguity in the Language of the Model 75 The Applicability of a Domain Concept 76 Integration with Legacy Code or Third Party Code 78 Your Domain Model Is not Your Enterprise Model 79 Use Bounded Contexts to Divide and Conquer a Large Model 79 Defining a Model's Boundary 82 Define Boundaries around Language 82 Align to Business Capabilities 83 Create Contexts around Teams 83 Try to Retain Some Communication between Teams 84 Context Game 85 The Difference between a Subdomain and a Bounded Context 85 Implementing Bounded Contexts 85 The Salient Points 89 CHAPTER 7: CONTEXT MAPPING 91 A Reality Map 92 The Technical Reality 92 The Organizational Reality 93 Mapping a Relevant Reality 94 X Marks the Spot of the Core Domain 94 Recognising the Relationships between Bounded Contexts 95 Anticorruption Layer 95 Shared Kernel 96 Open Host Service 97 Separate Ways 97 Partnership 98 An Upstream/Downstream Relationship 98 Customer
Supplier 99 Conformist 100 Communicating the Context Map 100 The Strategic Importance of Context Maps 101 Retaining Integrity 101 The Basis for a Plan of Attack 101 Understanding Ownership and Responsibility 101 Revealing Areas of Confusion in Business Work Flow 102 Identifying Nontechnical Obstacles 102 Encourages Good Communication 102 Helps On
Board New Starters 102 The Salient Points 103 CHAPTER 8: APPLICATION ARCHITECTURE 105 Application Architecture 105 Separating the Concerns of Your Application 106 Abstraction from the Complexities of the Domain 106 A Layered Architecture 106 Dependency Inversion 107 The Domain Layer 107 The Application Service Layer 108 The Infrastructural Layers 108 Communication Across Layers 108 Testing in Isolation 109 Don t Share Data Schema between Bounded Contexts 109 Application Architectures versus Architectures for Bounded Contexts 111 Application Services 112 Application Logic versus Domain Logic 114 Defining and Exposing Capabilities 114 Business Use Case Coordination 115 Application Services Represent Use Cases, Not Create, Read, Update, and Delete 115 Domain Layer As an Implementation Detail 115 Domain Reporting 116 Read Models versus Transactional Models 116 Application Clients 117 The Salient Points 120 CHAPTER 9: COMMON PROBLEMS FOR TEAMS STARTING OUT WITH DOMAIN
DRIVEN DESIGN 121 Overemphasizing the Importance of Tactical Patterns 122 Using the Same Architecture for All Bounded Contexts 122 Striving for Tactical Pattern Perfection 122 Mistaking the Building Blocks for the Value of DDD 123 Focusing on Code Rather Than the Principles of DDD 123 Missing the Real Value of DDD: Collaboration, Communication, and Context 124 Producing a Big Ball of Mud Due to Underestimating the Importance of Context 124 Causing Ambiguity and Misinterpretations by Failing to Create a UL 125 Designing Technical
Focused Solutions Due to a Lack of Collaboration 125 Spending Too Much Time on What's Not Important 126 Making Simple Problems Complex 126 Applying DDD Principles to a Trivial Domain with Little Business Expectation 126 Disregarding CRUD as an Antipattern 127 Using the Domain Model Pattern for Every Bounded Context 127 Ask Yourself: Is It Worth This Extra Complexity? 127 Underestimating the Cost of Applying DDD 127 Trying to Succeed Without a Motivated and Focused Team 128 Attempting Collaboration When a Domain Expert Is Not Behind the Project 128 Learning in a Noniterative Development Methodology 128 Applying DDD to Every Problem 129 Sacrificing Pragmatism for Needless Purity 129 Wasted Effort by Seeking Validation 129 Always Striving for Beautiful Code 130 DDD Is About Providing Value 130 The Salient Points 130 CHAPTER 10: APPLYING THE PRINCIPLES, PRACTICES, AND PATTERNS OF DDD 131 Selling DDD 132 Educating Your Team 132 Speaking to Your Business 132 Applying the Principles of DDD 133 Understand the Vision 133 Capture the Required Behaviors 134 Distilling the Problem Space 134 Focus on What Is Important 134 Understand the Reality of the Landscape 135 Modeling a Solution 135 All Problems Are Not Created Equal 136 Engaging with an Expert 136 Select a Behavior and Model Around a Concrete Scenario 137 Collaborate with the Domain Expert on the Most Interesting Parts 137 Evolve UL to Remove Ambiguity 138 Throw Away Your First Model, and Your Second 138 Implement the Model in Code 139 Creating a Domain Model 139 Keep the Solution Simple and Your Code Boring 139 Carve Out an Area of Safety 140 Integrate the Model Early and Often 140 Nontechnical Refactoring 140 Decompose Your Solution Space 140 Rinse and Repeat 141 Exploration and Experimentation 142 Challenge Your Assumptions 142 Modeling Is a Continuous Activity 142 There Are No Wrong Models 142 Supple Code Aids Discovery 143 Making the Implicit Explicit 143 Tackling Ambiguity 144 Give Things a Name 145 A Problem Solver First, A Technologist Second 146 Don't Solve All the Problems 146 How Do I Know That I Am Doing It Right? 146 Good Is Good Enough 147 Practice, Practice, Practice 147 The Salient Points 147 PART II: STRATEGIC PATTERNS: COMMUNICATING BETWEEN BOUNDED CONTEXTS CHAPTER 11: INTRODUCTION TO BOUNDED CONTEXT INTEGRATION 151 How to Integrate Bounded Contexts 152 Bounded Contexts Are Autonomous 153 The Challenges of Integrating Bounded Contexts at the Code Level 153 Multiple Bounded Contexts Exist within a Solution 153 Namespaces or Projects to Keep Bounded Contexts Separate 154 Integrating via the Database 155 Multiple Teams Working in a Single Codebase 156 Models Blur 156 Use Physical Boundaries to Enforce Clean Models 157 Integrating with Legacy Systems 158 Bubble Context 158 Autonomous Bubble Context 158 Exposing Legacy Systems as Services 160 Integrating Distributed Bounded Contexts 161 Integration Strategies for Distributed Bounded Contexts 161 Database Integration 162 Flat File Integration 163 RPC 164 Messaging 165 REST 165 The Challenges of DDD with Distributed Systems 165 The Problem with RPC 166 RPC Is Harder to Make Resilient 167 RPC Costs More to Scale 167 RPC Involves Tight Coupling 168 Distributed Transactions Hurt Scalability and Reliability 169 Bounded Contexts Don't Have to Be Consistent with Each Other 169 Eventual Consistency 169 Event
Driven Reactive DDD 170 Demonstrating the Resilience and Scalability of Reactive Solutions 171 Challenges and Trade
Offs of Asynchronous Messaging 173 Is RPC Still Relevant? 173 SOA and Reactive DDD 174 View Your Bounded Contexts as SOA Services 175 Decompose Bounded Contexts into Business Components 175 Decompose Business Components into Components 176 Going Even Further with Micro Service Architecture 178 The Salient Points 180 CHAPTER 12: INTEGRATING VIA MESSAGING 181 Messaging Fundamentals 182 Message Bus 182 Reliable Messaging 184 Store
and
Forward 184 Commands and Events 185 Eventual Consistency 186 Building an E
Commerce Application with NServiceBus 186 Designing the System 187 Domain
Driven Design 187 Containers Diagrams 188 Evolutionary Architecture 191 Sending Commands from a Web Application 192 Creating a Web Application to Send Messages with NServiceBus 192 Sending Commands 197 Handling Commands and Publishing Events 200 Creating an NServiceBus Server to Handle Commands 200 Configuring the Solution for Testing and Debugging 201 Publishing Events 204 Subscribing to Events 206 Making External HTTP Calls Reliable with Messaging Gateways 208 Messaging Gateways Improve Fault Tolerance 208 Implementing a Messaging Gateway 209 Controlling Message Retries 212 Eventual Consistency in Practice 215 Dealing with Inconsistency 215 Rolling Forward into New States 215 Bounded Contexts Store All the Data They Need Locally 216 Storage Is Cheap-Keep a Local Copy 217 Common Data Duplication Concerns 223 Pulling It All Together in the UI 224 Business Components Need Their Own APIs 225 Be Wary of Server
Side Orchestration 226 UI Composition with AJAX Data 226 UI Composition with AJAX HTML 226 Sharing Your APIs with the Outside World 227 Maintaining a Messaging Application 227 Message Versioning 228 Backward
Compatible Message Versioning 228 Handling Versioning with NServiceBus's Polymorphic Handlers 229 Monitoring and Scaling 233 Monitoring Errors 233 Monitoring SLAs 234 Scaling Out 235 Integrating a Bounded Context with Mass Transit 235 Messaging Bridge 236 Mass Transit 236 Installing and Configuring Mass Transit 236 Declaring Messages for Use by Mass Transit 238 Creating a Message Handler 239 Subscribing to Events 239 Linking the Systems with a Messaging Bridge 240 Publishing Events 242 Testing It Out 243 Where to Learn More about Mass Transit 243 The Salient Points 243 CHAPTER 13: INTEGRATING VIA HTTP WITH RPC AND REST 245 Why Prefer HTTP? 247 No Platform Coupling 247 Everyone Understands HTTP 247 Lots of Mature Tooling and Libraries 247 Dogfooding Your APIs 247 RPC 248 Implementing RPC over HTTP 248 SOAP 249 Plain XML or JSON: The Modern Approach to RPC 259 Choosing a Flavor of RPC 263 REST 264 Demystifying REST 264 Resources 264 Hypermedia 265 Statelessness 265 REST Fully Embraces HTTP 266 What REST Is Not 267 REST for Bounded Context Integration 268 Designing for REST 268 Building Event
Driven REST Systems with ASP.NET Web API 273 Maintaining REST Applications 303 Versioning 303 Monitoring and Metrics 303 Drawbacks with REST for Bounded Context Integration 304 Less Fault Tolerance Out of the Box 304 Eventual Consistency 304 The Salient Points 305 PART III: TACTICAL PATTERNS: CREATING EFFECTIVE DOMAIN MODELS CHAPTER 14: INTRODUCING THE DOMAIN MODELING BUILDING BLOCKS 309 Tactical Patterns 310 Patterns to Model Your Domain 310 Entities 310 Value Objects 314 Domain Services 317 Modules 318 Lifecycle Patterns 318 Aggregates 318 Factories 322 Repositories 323 Emerging Patterns 324 Domain Events 324 Event Sourcing 326 The Salient Points 327 CHAPTER 15: VALUE OBJECTS 329 When to Use a Value Object 330 Representing a Descriptive, Identity
Less Concept 330 Enhancing Explicitness 331 Defining Characteristics 333 Identity
Less 333 Attribute
Based Equality 333 Behavior
Rich 337 Cohesive 337 Immutable 337 Combinable 339 Self
Validating 341 Testable 344 Common Modeling Patterns 345 Static Factory Methods 345 Micro Types (Also Known as Tiny Types) 347 Collection Aversion 349 Persistence 35 NoSQL 352 SQL 353 Flat Denormalization 353 Normalizing into Separate Tables 357 The Salient Points 359 CHAPTER 16: ENTITIES 36 Understanding Entities 362 Domain Concepts with Identity and Continuity 362 Context
Dependent 363 Implementing Entities 363 Assigning Identifiers 363 Natural Keys 363 Arbitrarily Generated IDs 364 Datastore
Generated IDs 368 Pushing Behavior into Value Objects and Domain Services 369 Validating and Enforcing Invariants 371 Focusing on Behavior, Not Data 374 Avoiding the "Model the Real
World" Fallacy 377 Designing for Distribution 378 Common Entity Modeling Principles and Patterns 380 Implementing Validation and Invariants with Specifications 380 Avoid the State Pattern; Use Explicit Modeling 382 Avoiding Getters and Setters with the Memento Pattern 385 Favor Hidden
Side
Effect
Free Functions 386 The Salient Points 388 CHAPTER 17: DOMAIN SERVICES 389 Understanding Domain Services 390 When to Use a Domain Service 390 Encapsulating Business Policies and Processes 390 Representing Contracts 394 Anatomy of a Domain Service 395 Avoiding Anemic Domain Models 395 Contrasting with Application Services 396 Utilizing Domain Services 397 In the Service Layer 397 In the Domain 398 Manually Wiring Up 399 Using Dependency Injection 400 Using a Service Locator 400 Applying Double Dispatch 401 Decoupling with Domain Events 402 Should Entities Even Know About Domain Services? 403 The Salient Points 403 CHAPTER 18: DOMAIN EVENTS 405 Essence of the Domain Events Pattern 406 Important Domain Occurrences That Have Already Happened 406 Reacting to Events 407 Optional Asynchrony 407 Internal vs External Events 408 Event Handling Actions 409 Invoke Domain Logic 409 Invoke Application Logic 410 Domain Events' Implementation Patterns 410 Use the .Net Framework's Events Model 410 Use an In
Memory Bus 412 Udi Dahan's Static DomainEvents Class 415 Handling Threading Issues 417 Avoid a Static Class by Using Method Injection 418 Return Domain Events 419 Use an IoC Container as an Event Dispatcher 421 Testing Domain Events 422 Unit Testing 422 Application Service Layer Testing 424 The Salient Points 425 CHAPTER 19: AGGREGATES 427 Managing Complex Object Graphs 428 Favoring a Single Traversal Direction 428 Qualifying Associations 430 Preferring IDs Over Object References 431 Aggregates 434 Design Around Domain Invariants 435 Higher Level of Domain Abstraction 435 Consistency Boundaries 435 Transactional Consistency Internally 436 Eventual Consistency Externally 439 Special Cases 440 Favor Smaller Aggregates 441 Large Aggregates Can Degrade Performance 441 Large Aggregates Are More Susceptible to Concurrency Conflicts 442 Large Aggregates May Not Scale Well 442 Defining Aggregate Boundaries 442 eBidder: The Online Auction Case Study 443 Aligning with Invariants 444 Aligning with Transactions and Consistency 446 Ignoring User Interface Influences 448 Avoiding Dumb Collections and Containers 448 Don't Focus on HAS
A Relationships 449 Refactoring to Aggregates 449 Satisfying Business Use Cases-Not Real Life 449 Implementing Aggregates 450 Selecting an Aggregate Root 450 Exposing Behavioral Interfaces 452 Protecting Internal State 453 Allowing Only Roots to Have Global Identity 454 Referencing Other Aggregates 454 Nothing Outside An Aggregate's Boundary May Hold a Reference to Anything Inside 455 The Aggregate Root Can Hand Out Transient References to the Internal Domain Objects 456 Objects within the Aggregate Can Hold References to Other Aggregate Roots 456 Implementing Persistence 458 Access to Domain Objects for Reading Can Be at the Database Level 460 A Delete Operation Must Remove Everything within the Aggregate Boundary at Once 461 Avoiding Lazy Loading 461 Implementing Transactional Consistency 462 Implementing Eventual Consistency 463 Rules That Span Multiple Aggregates 463 Asynchronous Eventual Consistency 464 Implementing Concurrency 465 The Salient Points 468 CHAPTER 20: FACTORIES 469 The Role of a Factory 469 Separating Use from Construction 470 Encapsulating Internals 470 Hiding Decisions on Creation Type 472 Factory Methods on Aggregates 474 Factories for Reconstitution 475 Use Factories Pragmatically 477 The Salient Points 477 CHAPTER 21: REPOSITORIES 479 Repositories 479 A Misunderstood Pattern 481 Is the Repository an Antipattern? 481 The Difference between a Domain Model and a Persistence Model 482 The Generic Repository 483 Aggregate Persistence Strategies 486 Using a Persistence Framework That Can Map the Domain Model to the Data Model without Compromise 486 Using a Persistence Framework That Cannot Map the Domain Model Directly without Compromise 487 Public Getters and Setters 487 Using the Memento Pattern 488 Event Streams 49 Be Pragmatic 491 A Repository Is an Explicit Contract 492 Transaction Management and Units of Work 493 To Save or Not To Save 497 Persistence Frameworks That Track Domain Object Changes 497 Having to Explicitly Save Changes to Aggregates 498 The Repository as an Anticorruption Layer 499 Other Responsibilities of a Repository 500 Entity ID Generation 500 Collection Summaries 502 Concurrency 503 Audit Trails 506 Repository Antipatterns 506 Antipatterns: Don't Support Ad Hoc Queries 506 Antipatterns: Lazy Loading Is Design Smell 507 Antipatterns: Don't Use Repositories for Reporting Needs 507 Repository Implementations 508 Persistence Framework Can Map Domain Model to Data Model without Compromise 509 NHibernate Example 509 RavenDB Example 543 Persistence Framework Cannot Map Domain Model Directly without Compromise 557 Entity Framework Example 558 Micro ORM Example 577 The Salient Points 593 CHAPTER 22: EVENT SOURCING 595 The Limitations of Storing State as a Snapshot 596 Gaining Competitive Advantage by Storing State as a Stream of Events 597 Temporal Queries 597 Projections 599 Snapshots 599 Event
Sourced Aggregates 600 Structuring 600 Adding Event
Sourcing Capabilities 601 Exposing Expressive Domain
Focused APIs 602 Adding Snapshot Support 604 Persisting and Rehydrating 605 Creating an Event-Sourcing Repository 605 Adding Snapshot Persistence and Reloading 607 Handling Concurrency 609 Testing 610 Building an Event Store 611 Designing a Storage Format 612 Creating Event Streams 614 Appending to Event Streams 614 Querying Event Streams 615 Adding Snapshot Support 616 Managing Concurrency 618 A SQL Server
Based Event Store 621 Choosing a Schema 621 Creating a Stream 622 Saving Events 623 Loading Events from a Stream 624 Snapshots 625 Is Building Your Own Event Store a Good Idea? 627 Using the Purpose
Built Event Store 627 Installing Greg Young's Event Store 628 Using the C# Client Library 627 Running Temporal Queries 632 Querying a Single Stream 632 Querying Multiple Streams 634 Creating Projections 635 CQRS with Event Sourcing 637 Using Projections to Create View Caches 638 CQRS and Event Sourcing Synergy 638 Event Streams as Queues 639 No TwöPhase Commits 639 Recapping the Benefits of Event Sourcing 639 Competitive Business Advantage 639 Expressive Behavior
Focused Aggregates 639 Simplified Persistence 640 Superior Debugging 640 Weighing the Costs of Event Sourcing 640 Versioning 640 New Concepts to Learn and Skills to Hone 640 New Technologies to Learn and Master 641 Greater Data Storage Requirements 641 Additional Learning Resources 641 The Salient Points 641 PART IV: DESIGN PATTERNS FOR EFFECTIVE APPLICATIONS CHAPTER 23: ARCHITECTING APPLICATION USER INTERFACES 645 Design Considerations 646 Owned UIs versus Composed UIs 646 Autonomous 646 Authoritative 647 Some Help Deciding 648 HTML APIs versus Data APIs 649 Client versus Server
Side Aggregation/Coordination 649 Example 1: An HTML API
Based, Server
Side UI for Nondistributed Bounded Contexts 651 Example 2: A Data API
Based, Client
Side UI for Distributed Bounded Contexts 658 The Salient Points 667 CHAPTER 24: CQRS: AN ARCHITECTURE OF A BOUNDED CONTEXT 669 The Challenges of Maintaining a Single Model for Two Contexts 670 A Better Architecture for Complex Bounded Contexts 670 The Command Side: Business Tasks 672 Explicitly Modeling Intent 672 A Model Free from Presentational Distractions 674 Handling a Business Request 675 The Query Side: Domain Reporting 676 Reports Mapped Directly to the Data Model 676 Materialized Views Built from Domain Events 678 The Misconceptions of CQRS 679 CQRS Is Hard 679 CQRS Is Eventually Consistent 679 Your Models Need to Be Event Sourced 680 Commands Should Be Asynchronous 680 CQRS Only Works with Messaging Systems 680 You Need to Use Do
DRIVEN DESIGN CHAPTER 1: WHAT IS DOMAIN
DRIVEN DESIGN? 3 The Challenges of Creating Software for Complex Problem Domains 4 Code Created Without a Common Language 4 A Lack of Organization 5 The Ball of Mud Pattern Stifles Development 5 A Lack of Focus on the Problem Domain 6 How the Patterns of Domain
Driven Design Manage Complexity 6 The Strategic Patterns of DDD 6 Distilling the Problem Domain to Reveal What Is Important 7 Creating a Model to Solve Domain Problems 7 Using a Shared Language to Enable Modeling Collaboration 7 Isolate Models from Ambiguity and Corruption 8 Understanding the Relationships between Contexts 9 The Tactical Patterns of DDD 9 The Problem Space and the Solution Space 9 The Practices and Principles of Domain
Driven Design 11 Focusing on the Core Domain 11 Learning through Collaboration 11 Creating Models through Exploration and Experimentation 11 Communication 11 Understanding the Applicability of a Model 12 Constantly Evolving the Model 12 Popular Misconceptions of Domain
Driven Design 12 Tactical Patterns Are Key to DDD 12 DDD Is a Framework 13 DDD Is a Silver Bullet 13 The Salient Points 13 CHAPTER 2: DISTILLING THE PROBLEM DOMAIN 15 Knowledge Crunching and Collaboration 15 Reaching a Shared Understanding through a Shared Language 16 The Importance of Domain Knowledge 17 The Role of Business Analysts 17 An Ongoing Process 17 Gaining Domain Insight with Domain Experts 18 Domain Experts vs Stakeholders 18 Deeper Understanding for the Business 19 Engaging with Your Domain Experts 19 Patterns for Effective Knowledge Crunching 19 Focus on the Most Interesting Conversations 19 Start from the Use Cases 20 Ask Powerful Questions 20 Sketching 20 Class Responsibility Collaboration Cards 21 Defer the Naming of Concepts in Your Model 21 Behavior
Driven Development 22 Rapid Prototyping 23 Look at Paper
Based Systems 24 Look For Existing Models 24 Understanding Intent 24 Event Storming 25 Impact Mapping 25 Understanding the Business Model 27 Deliberate Discovery 28 Model Exploration Whirlpool 29 The Salient Points 29 CHAPTER 3: FOCUSING ON THE CORE DOMAIN 31 Why Decompose a Problem Domain? 31 How to Capture the Essence of the Problem 32 Look Beyond Requirements 32 Capture the Domain Vision for a Shared Understanding of What Is Core 32 How to Focus on the Core Problem 33 Distilling a Problem Domain 34 Core Domains 35 Treat Your Core Domain as a Product Rather than a Project 36 Generic Domains 37 Supporting Domains 37 How Subdomains Shape a Solution 37 Not All Parts of a System will be Well Designed 37 Focus on Clean Boundaries over Perfect Models 38 The Core Domain Doesn't Always Have to Be Perfect the First Time 39 Build Subdomains for Replacement Rather than Reuse 39 What if You Have no Core Domain? 39 The Salient Points 40 CHAPTER 4: MODEL
DRIVEN DESIGN 41 What Is a Domain Model? 42 The Domain versus the Domain Model 42 The Analysis Model 43 The Code Model 43 The Code Model Is the Primary Expression of the Domain Model 44 Model
Driven Design 44 The Challenges with Upfront Design 44 Team Modeling 45 Using a Ubiquitous Language to Bind the Analysis to the Code Model 47 A Language Will Outlive Your Software 47 The Language of the Business 48 Translation between the Developers and the Business 48 Collaborating on a Ubiquitous Language 48 Carving Out a Language by Working with Concrete Examples 49 Teach Your Domain Experts to Focus on the Problem and Not Jump to a Solution 50 Best Practices for Shaping the Language 51 How to Create Effective Domain Models 52 Don't Let the Truth Get in the Way of a Good Model 52 Model Only What Is Relevant 54 Domain Models Are Temporarily Useful 54 Be Explicit with Terminology 54 Limit Your Abstractions 54 Focus Your Code at the Right Level of Abstraction 55 Abstract Behavior Not Implementations 55 Implement the Model in Code Early and Often 56 Don't Stop at the First Good Idea 56 When to Apply Model
Driven Design 56 If It's Not Worth the Effort Don't Try and Model It 56 Focus on the Core Domain 57 The Salient Points 57 CHAPTER 5: DOMAIN MODEL IMPLEMENTATION PATTERNS 59 The Domain Layer 60 Domain Model Implementation Patterns 60 Domain Model 62 Transaction Script 65 Table Module 67 Active Record 67 Anemic Domain Model 67 Anemic Domain Model and Functional Programming 68 The Salient Points 71 CHAPTER 6: MAINTAINING THE INTEGRITY OF DOMAIN MODELS WITH BOUNDED CONTEXTS 73 The Challenges of a Single Model 74 A Model Can Grow in Complexity 74 Multiple Teams Working on a Single Model 74 Ambiguity in the Language of the Model 75 The Applicability of a Domain Concept 76 Integration with Legacy Code or Third Party Code 78 Your Domain Model Is not Your Enterprise Model 79 Use Bounded Contexts to Divide and Conquer a Large Model 79 Defining a Model's Boundary 82 Define Boundaries around Language 82 Align to Business Capabilities 83 Create Contexts around Teams 83 Try to Retain Some Communication between Teams 84 Context Game 85 The Difference between a Subdomain and a Bounded Context 85 Implementing Bounded Contexts 85 The Salient Points 89 CHAPTER 7: CONTEXT MAPPING 91 A Reality Map 92 The Technical Reality 92 The Organizational Reality 93 Mapping a Relevant Reality 94 X Marks the Spot of the Core Domain 94 Recognising the Relationships between Bounded Contexts 95 Anticorruption Layer 95 Shared Kernel 96 Open Host Service 97 Separate Ways 97 Partnership 98 An Upstream/Downstream Relationship 98 Customer
Supplier 99 Conformist 100 Communicating the Context Map 100 The Strategic Importance of Context Maps 101 Retaining Integrity 101 The Basis for a Plan of Attack 101 Understanding Ownership and Responsibility 101 Revealing Areas of Confusion in Business Work Flow 102 Identifying Nontechnical Obstacles 102 Encourages Good Communication 102 Helps On
Board New Starters 102 The Salient Points 103 CHAPTER 8: APPLICATION ARCHITECTURE 105 Application Architecture 105 Separating the Concerns of Your Application 106 Abstraction from the Complexities of the Domain 106 A Layered Architecture 106 Dependency Inversion 107 The Domain Layer 107 The Application Service Layer 108 The Infrastructural Layers 108 Communication Across Layers 108 Testing in Isolation 109 Don t Share Data Schema between Bounded Contexts 109 Application Architectures versus Architectures for Bounded Contexts 111 Application Services 112 Application Logic versus Domain Logic 114 Defining and Exposing Capabilities 114 Business Use Case Coordination 115 Application Services Represent Use Cases, Not Create, Read, Update, and Delete 115 Domain Layer As an Implementation Detail 115 Domain Reporting 116 Read Models versus Transactional Models 116 Application Clients 117 The Salient Points 120 CHAPTER 9: COMMON PROBLEMS FOR TEAMS STARTING OUT WITH DOMAIN
DRIVEN DESIGN 121 Overemphasizing the Importance of Tactical Patterns 122 Using the Same Architecture for All Bounded Contexts 122 Striving for Tactical Pattern Perfection 122 Mistaking the Building Blocks for the Value of DDD 123 Focusing on Code Rather Than the Principles of DDD 123 Missing the Real Value of DDD: Collaboration, Communication, and Context 124 Producing a Big Ball of Mud Due to Underestimating the Importance of Context 124 Causing Ambiguity and Misinterpretations by Failing to Create a UL 125 Designing Technical
Focused Solutions Due to a Lack of Collaboration 125 Spending Too Much Time on What's Not Important 126 Making Simple Problems Complex 126 Applying DDD Principles to a Trivial Domain with Little Business Expectation 126 Disregarding CRUD as an Antipattern 127 Using the Domain Model Pattern for Every Bounded Context 127 Ask Yourself: Is It Worth This Extra Complexity? 127 Underestimating the Cost of Applying DDD 127 Trying to Succeed Without a Motivated and Focused Team 128 Attempting Collaboration When a Domain Expert Is Not Behind the Project 128 Learning in a Noniterative Development Methodology 128 Applying DDD to Every Problem 129 Sacrificing Pragmatism for Needless Purity 129 Wasted Effort by Seeking Validation 129 Always Striving for Beautiful Code 130 DDD Is About Providing Value 130 The Salient Points 130 CHAPTER 10: APPLYING THE PRINCIPLES, PRACTICES, AND PATTERNS OF DDD 131 Selling DDD 132 Educating Your Team 132 Speaking to Your Business 132 Applying the Principles of DDD 133 Understand the Vision 133 Capture the Required Behaviors 134 Distilling the Problem Space 134 Focus on What Is Important 134 Understand the Reality of the Landscape 135 Modeling a Solution 135 All Problems Are Not Created Equal 136 Engaging with an Expert 136 Select a Behavior and Model Around a Concrete Scenario 137 Collaborate with the Domain Expert on the Most Interesting Parts 137 Evolve UL to Remove Ambiguity 138 Throw Away Your First Model, and Your Second 138 Implement the Model in Code 139 Creating a Domain Model 139 Keep the Solution Simple and Your Code Boring 139 Carve Out an Area of Safety 140 Integrate the Model Early and Often 140 Nontechnical Refactoring 140 Decompose Your Solution Space 140 Rinse and Repeat 141 Exploration and Experimentation 142 Challenge Your Assumptions 142 Modeling Is a Continuous Activity 142 There Are No Wrong Models 142 Supple Code Aids Discovery 143 Making the Implicit Explicit 143 Tackling Ambiguity 144 Give Things a Name 145 A Problem Solver First, A Technologist Second 146 Don't Solve All the Problems 146 How Do I Know That I Am Doing It Right? 146 Good Is Good Enough 147 Practice, Practice, Practice 147 The Salient Points 147 PART II: STRATEGIC PATTERNS: COMMUNICATING BETWEEN BOUNDED CONTEXTS CHAPTER 11: INTRODUCTION TO BOUNDED CONTEXT INTEGRATION 151 How to Integrate Bounded Contexts 152 Bounded Contexts Are Autonomous 153 The Challenges of Integrating Bounded Contexts at the Code Level 153 Multiple Bounded Contexts Exist within a Solution 153 Namespaces or Projects to Keep Bounded Contexts Separate 154 Integrating via the Database 155 Multiple Teams Working in a Single Codebase 156 Models Blur 156 Use Physical Boundaries to Enforce Clean Models 157 Integrating with Legacy Systems 158 Bubble Context 158 Autonomous Bubble Context 158 Exposing Legacy Systems as Services 160 Integrating Distributed Bounded Contexts 161 Integration Strategies for Distributed Bounded Contexts 161 Database Integration 162 Flat File Integration 163 RPC 164 Messaging 165 REST 165 The Challenges of DDD with Distributed Systems 165 The Problem with RPC 166 RPC Is Harder to Make Resilient 167 RPC Costs More to Scale 167 RPC Involves Tight Coupling 168 Distributed Transactions Hurt Scalability and Reliability 169 Bounded Contexts Don't Have to Be Consistent with Each Other 169 Eventual Consistency 169 Event
Driven Reactive DDD 170 Demonstrating the Resilience and Scalability of Reactive Solutions 171 Challenges and Trade
Offs of Asynchronous Messaging 173 Is RPC Still Relevant? 173 SOA and Reactive DDD 174 View Your Bounded Contexts as SOA Services 175 Decompose Bounded Contexts into Business Components 175 Decompose Business Components into Components 176 Going Even Further with Micro Service Architecture 178 The Salient Points 180 CHAPTER 12: INTEGRATING VIA MESSAGING 181 Messaging Fundamentals 182 Message Bus 182 Reliable Messaging 184 Store
and
Forward 184 Commands and Events 185 Eventual Consistency 186 Building an E
Commerce Application with NServiceBus 186 Designing the System 187 Domain
Driven Design 187 Containers Diagrams 188 Evolutionary Architecture 191 Sending Commands from a Web Application 192 Creating a Web Application to Send Messages with NServiceBus 192 Sending Commands 197 Handling Commands and Publishing Events 200 Creating an NServiceBus Server to Handle Commands 200 Configuring the Solution for Testing and Debugging 201 Publishing Events 204 Subscribing to Events 206 Making External HTTP Calls Reliable with Messaging Gateways 208 Messaging Gateways Improve Fault Tolerance 208 Implementing a Messaging Gateway 209 Controlling Message Retries 212 Eventual Consistency in Practice 215 Dealing with Inconsistency 215 Rolling Forward into New States 215 Bounded Contexts Store All the Data They Need Locally 216 Storage Is Cheap-Keep a Local Copy 217 Common Data Duplication Concerns 223 Pulling It All Together in the UI 224 Business Components Need Their Own APIs 225 Be Wary of Server
Side Orchestration 226 UI Composition with AJAX Data 226 UI Composition with AJAX HTML 226 Sharing Your APIs with the Outside World 227 Maintaining a Messaging Application 227 Message Versioning 228 Backward
Compatible Message Versioning 228 Handling Versioning with NServiceBus's Polymorphic Handlers 229 Monitoring and Scaling 233 Monitoring Errors 233 Monitoring SLAs 234 Scaling Out 235 Integrating a Bounded Context with Mass Transit 235 Messaging Bridge 236 Mass Transit 236 Installing and Configuring Mass Transit 236 Declaring Messages for Use by Mass Transit 238 Creating a Message Handler 239 Subscribing to Events 239 Linking the Systems with a Messaging Bridge 240 Publishing Events 242 Testing It Out 243 Where to Learn More about Mass Transit 243 The Salient Points 243 CHAPTER 13: INTEGRATING VIA HTTP WITH RPC AND REST 245 Why Prefer HTTP? 247 No Platform Coupling 247 Everyone Understands HTTP 247 Lots of Mature Tooling and Libraries 247 Dogfooding Your APIs 247 RPC 248 Implementing RPC over HTTP 248 SOAP 249 Plain XML or JSON: The Modern Approach to RPC 259 Choosing a Flavor of RPC 263 REST 264 Demystifying REST 264 Resources 264 Hypermedia 265 Statelessness 265 REST Fully Embraces HTTP 266 What REST Is Not 267 REST for Bounded Context Integration 268 Designing for REST 268 Building Event
Driven REST Systems with ASP.NET Web API 273 Maintaining REST Applications 303 Versioning 303 Monitoring and Metrics 303 Drawbacks with REST for Bounded Context Integration 304 Less Fault Tolerance Out of the Box 304 Eventual Consistency 304 The Salient Points 305 PART III: TACTICAL PATTERNS: CREATING EFFECTIVE DOMAIN MODELS CHAPTER 14: INTRODUCING THE DOMAIN MODELING BUILDING BLOCKS 309 Tactical Patterns 310 Patterns to Model Your Domain 310 Entities 310 Value Objects 314 Domain Services 317 Modules 318 Lifecycle Patterns 318 Aggregates 318 Factories 322 Repositories 323 Emerging Patterns 324 Domain Events 324 Event Sourcing 326 The Salient Points 327 CHAPTER 15: VALUE OBJECTS 329 When to Use a Value Object 330 Representing a Descriptive, Identity
Less Concept 330 Enhancing Explicitness 331 Defining Characteristics 333 Identity
Less 333 Attribute
Based Equality 333 Behavior
Rich 337 Cohesive 337 Immutable 337 Combinable 339 Self
Validating 341 Testable 344 Common Modeling Patterns 345 Static Factory Methods 345 Micro Types (Also Known as Tiny Types) 347 Collection Aversion 349 Persistence 35 NoSQL 352 SQL 353 Flat Denormalization 353 Normalizing into Separate Tables 357 The Salient Points 359 CHAPTER 16: ENTITIES 36 Understanding Entities 362 Domain Concepts with Identity and Continuity 362 Context
Dependent 363 Implementing Entities 363 Assigning Identifiers 363 Natural Keys 363 Arbitrarily Generated IDs 364 Datastore
Generated IDs 368 Pushing Behavior into Value Objects and Domain Services 369 Validating and Enforcing Invariants 371 Focusing on Behavior, Not Data 374 Avoiding the "Model the Real
World" Fallacy 377 Designing for Distribution 378 Common Entity Modeling Principles and Patterns 380 Implementing Validation and Invariants with Specifications 380 Avoid the State Pattern; Use Explicit Modeling 382 Avoiding Getters and Setters with the Memento Pattern 385 Favor Hidden
Side
Effect
Free Functions 386 The Salient Points 388 CHAPTER 17: DOMAIN SERVICES 389 Understanding Domain Services 390 When to Use a Domain Service 390 Encapsulating Business Policies and Processes 390 Representing Contracts 394 Anatomy of a Domain Service 395 Avoiding Anemic Domain Models 395 Contrasting with Application Services 396 Utilizing Domain Services 397 In the Service Layer 397 In the Domain 398 Manually Wiring Up 399 Using Dependency Injection 400 Using a Service Locator 400 Applying Double Dispatch 401 Decoupling with Domain Events 402 Should Entities Even Know About Domain Services? 403 The Salient Points 403 CHAPTER 18: DOMAIN EVENTS 405 Essence of the Domain Events Pattern 406 Important Domain Occurrences That Have Already Happened 406 Reacting to Events 407 Optional Asynchrony 407 Internal vs External Events 408 Event Handling Actions 409 Invoke Domain Logic 409 Invoke Application Logic 410 Domain Events' Implementation Patterns 410 Use the .Net Framework's Events Model 410 Use an In
Memory Bus 412 Udi Dahan's Static DomainEvents Class 415 Handling Threading Issues 417 Avoid a Static Class by Using Method Injection 418 Return Domain Events 419 Use an IoC Container as an Event Dispatcher 421 Testing Domain Events 422 Unit Testing 422 Application Service Layer Testing 424 The Salient Points 425 CHAPTER 19: AGGREGATES 427 Managing Complex Object Graphs 428 Favoring a Single Traversal Direction 428 Qualifying Associations 430 Preferring IDs Over Object References 431 Aggregates 434 Design Around Domain Invariants 435 Higher Level of Domain Abstraction 435 Consistency Boundaries 435 Transactional Consistency Internally 436 Eventual Consistency Externally 439 Special Cases 440 Favor Smaller Aggregates 441 Large Aggregates Can Degrade Performance 441 Large Aggregates Are More Susceptible to Concurrency Conflicts 442 Large Aggregates May Not Scale Well 442 Defining Aggregate Boundaries 442 eBidder: The Online Auction Case Study 443 Aligning with Invariants 444 Aligning with Transactions and Consistency 446 Ignoring User Interface Influences 448 Avoiding Dumb Collections and Containers 448 Don't Focus on HAS
A Relationships 449 Refactoring to Aggregates 449 Satisfying Business Use Cases-Not Real Life 449 Implementing Aggregates 450 Selecting an Aggregate Root 450 Exposing Behavioral Interfaces 452 Protecting Internal State 453 Allowing Only Roots to Have Global Identity 454 Referencing Other Aggregates 454 Nothing Outside An Aggregate's Boundary May Hold a Reference to Anything Inside 455 The Aggregate Root Can Hand Out Transient References to the Internal Domain Objects 456 Objects within the Aggregate Can Hold References to Other Aggregate Roots 456 Implementing Persistence 458 Access to Domain Objects for Reading Can Be at the Database Level 460 A Delete Operation Must Remove Everything within the Aggregate Boundary at Once 461 Avoiding Lazy Loading 461 Implementing Transactional Consistency 462 Implementing Eventual Consistency 463 Rules That Span Multiple Aggregates 463 Asynchronous Eventual Consistency 464 Implementing Concurrency 465 The Salient Points 468 CHAPTER 20: FACTORIES 469 The Role of a Factory 469 Separating Use from Construction 470 Encapsulating Internals 470 Hiding Decisions on Creation Type 472 Factory Methods on Aggregates 474 Factories for Reconstitution 475 Use Factories Pragmatically 477 The Salient Points 477 CHAPTER 21: REPOSITORIES 479 Repositories 479 A Misunderstood Pattern 481 Is the Repository an Antipattern? 481 The Difference between a Domain Model and a Persistence Model 482 The Generic Repository 483 Aggregate Persistence Strategies 486 Using a Persistence Framework That Can Map the Domain Model to the Data Model without Compromise 486 Using a Persistence Framework That Cannot Map the Domain Model Directly without Compromise 487 Public Getters and Setters 487 Using the Memento Pattern 488 Event Streams 49 Be Pragmatic 491 A Repository Is an Explicit Contract 492 Transaction Management and Units of Work 493 To Save or Not To Save 497 Persistence Frameworks That Track Domain Object Changes 497 Having to Explicitly Save Changes to Aggregates 498 The Repository as an Anticorruption Layer 499 Other Responsibilities of a Repository 500 Entity ID Generation 500 Collection Summaries 502 Concurrency 503 Audit Trails 506 Repository Antipatterns 506 Antipatterns: Don't Support Ad Hoc Queries 506 Antipatterns: Lazy Loading Is Design Smell 507 Antipatterns: Don't Use Repositories for Reporting Needs 507 Repository Implementations 508 Persistence Framework Can Map Domain Model to Data Model without Compromise 509 NHibernate Example 509 RavenDB Example 543 Persistence Framework Cannot Map Domain Model Directly without Compromise 557 Entity Framework Example 558 Micro ORM Example 577 The Salient Points 593 CHAPTER 22: EVENT SOURCING 595 The Limitations of Storing State as a Snapshot 596 Gaining Competitive Advantage by Storing State as a Stream of Events 597 Temporal Queries 597 Projections 599 Snapshots 599 Event
Sourced Aggregates 600 Structuring 600 Adding Event
Sourcing Capabilities 601 Exposing Expressive Domain
Focused APIs 602 Adding Snapshot Support 604 Persisting and Rehydrating 605 Creating an Event-Sourcing Repository 605 Adding Snapshot Persistence and Reloading 607 Handling Concurrency 609 Testing 610 Building an Event Store 611 Designing a Storage Format 612 Creating Event Streams 614 Appending to Event Streams 614 Querying Event Streams 615 Adding Snapshot Support 616 Managing Concurrency 618 A SQL Server
Based Event Store 621 Choosing a Schema 621 Creating a Stream 622 Saving Events 623 Loading Events from a Stream 624 Snapshots 625 Is Building Your Own Event Store a Good Idea? 627 Using the Purpose
Built Event Store 627 Installing Greg Young's Event Store 628 Using the C# Client Library 627 Running Temporal Queries 632 Querying a Single Stream 632 Querying Multiple Streams 634 Creating Projections 635 CQRS with Event Sourcing 637 Using Projections to Create View Caches 638 CQRS and Event Sourcing Synergy 638 Event Streams as Queues 639 No TwöPhase Commits 639 Recapping the Benefits of Event Sourcing 639 Competitive Business Advantage 639 Expressive Behavior
Focused Aggregates 639 Simplified Persistence 640 Superior Debugging 640 Weighing the Costs of Event Sourcing 640 Versioning 640 New Concepts to Learn and Skills to Hone 640 New Technologies to Learn and Master 641 Greater Data Storage Requirements 641 Additional Learning Resources 641 The Salient Points 641 PART IV: DESIGN PATTERNS FOR EFFECTIVE APPLICATIONS CHAPTER 23: ARCHITECTING APPLICATION USER INTERFACES 645 Design Considerations 646 Owned UIs versus Composed UIs 646 Autonomous 646 Authoritative 647 Some Help Deciding 648 HTML APIs versus Data APIs 649 Client versus Server
Side Aggregation/Coordination 649 Example 1: An HTML API
Based, Server
Side UI for Nondistributed Bounded Contexts 651 Example 2: A Data API
Based, Client
Side UI for Distributed Bounded Contexts 658 The Salient Points 667 CHAPTER 24: CQRS: AN ARCHITECTURE OF A BOUNDED CONTEXT 669 The Challenges of Maintaining a Single Model for Two Contexts 670 A Better Architecture for Complex Bounded Contexts 670 The Command Side: Business Tasks 672 Explicitly Modeling Intent 672 A Model Free from Presentational Distractions 674 Handling a Business Request 675 The Query Side: Domain Reporting 676 Reports Mapped Directly to the Data Model 676 Materialized Views Built from Domain Events 678 The Misconceptions of CQRS 679 CQRS Is Hard 679 CQRS Is Eventually Consistent 679 Your Models Need to Be Event Sourced 680 Commands Should Be Asynchronous 680 CQRS Only Works with Messaging Systems 680 You Need to Use Do