Topic: C# and C++

Patterns, Principles, and Practices of Domain-Driven Design (1118714709) cover image

Patterns, Principles, and Practices of Domain-Driven Design

Scott Millett, Nick Tune
ISBN: 978-1-118-71470-6
Paperback
800 pages
May 2015
Other Available Formats: Wiley E-Text
If you are an instructor, you may request an evaluation copy for this title.
Paperback Version: US $59.99 Add to Cart

About This Title  |  Download Code  |  Errata  |  P2P Forum for This Title

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