CQRS by Example - Carlos Buenosvinos - E-Book

CQRS by Example E-Book

Carlos Buenosvinos

0,0
29,99 €

-100%
Sammeln Sie Punkte in unserem Gutscheinprogramm und kaufen Sie E-Books und Hörbücher mit bis zu 100% Rabatt.

Mehr erfahren.
Beschreibung

This course offers an in-depth exploration of the Command Query Responsibility Segregation (CQRS) pattern, a powerful architecture design that separates read and write operations to achieve greater scalability and performance in software systems. You'll begin by understanding the core principles behind CQRS and why it is essential for handling complex, high-traffic applications. Throughout the course, we’ll work through real-world examples that demonstrate how to apply CQRS to achieve a cleaner and more efficient codebase.
Next, we will guide you through the practical aspects of implementing CQRS in a variety of use cases, focusing on how it enhances system maintainability and performance. You'll learn to distinguish between commands and queries effectively, and how to manage data consistency across distributed systems using techniques like event sourcing and eventual consistency.
By the end of the course, you will have a comprehensive understanding of CQRS and its benefits. You'll be able to implement it in your own projects, whether you're building new applications or improving legacy systems. With a focus on scalability, maintainability, and performance, this course equips you with the skills needed to take on complex architectural challenges confidently.

Das E-Book können Sie in Legimi-Apps oder einer beliebigen App lesen, die das folgende Format unterstützen:

EPUB
MOBI

Seitenzahl: 288

Veröffentlichungsjahr: 2024

Bewertungen
0,0
0
0
0
0
0
Mehr Informationen
Mehr Informationen
Legimi prüft nicht, ob Rezensionen von Nutzern stammen, die den betreffenden Titel tatsächlich gekauft oder gelesen/gehört haben. Wir entfernen aber gefälschte Rezensionen.



CQRS by Example

Command-Query Responsibility Segregation is an architectural style for developing applications that split the Domain Model in Read and Write operations in order to maximize semantics, performance, and scalability. What are all the benefits of CQRS? What are the drawbacks? In which cases does it worth applying it? How does it relate to Hexagonal Architecture? How do we properly implement the Write Model and Read Models? How do we keep in sync both sides? What are the following steps to move towards Event Sourcing? This book will answer all these questions and many more, guided through lots of practical examples. Brought to you by the same authors behind “Domain-Driven Design in PHP”.

 

Carlos Buenosvinos, Christian Soronellas, and Keyvan Akbary

 

This version was published on 2024-09-02

© 2020 - 2024 Carlos Buenosvinos, Christian Soronellas, and Keyvan Akbary

Table of Contents

Foreword by Marco Pivetta

Preface

Domain-Driven Design in PHP

Domain-Driven Design Acceptance Has Rapidly Grown

CQRS by Example

Who Should Read This Book

Summary of Chapters

Code, Typos, and Examples

Acknowledgements

About the Authors

Carlos Buenosvinos

Christian Soronellas

Keyvan Akbary

CQRS and Domain-Driven Design

What’s All the Fuss About?

Why Domain-Driven Design Matters

The Three Pillars of Domain-Driven Design

Considering Domain-Driven Design

The Tricky Parts

Wrapup

A Journey Toward CQRS

Introducing Cheeper, a Twitter Clone

Architectural Styles

A Brief Analysis

Potential Limitations of Hexagonal Architecture

Wrapup

Anatomy of CQRS

Cheeper Use Case Analysis

Cheeper à la CQRS

CQRS Overview

Other CQRS Components

Two Sides of the Same Coin

The Command Side

The Query Side

Syncing the Command and Query Sides

Wrapup

Command Side and the Write Model

Commands

Command Handlers

Command Bus

Putting It All Together

Wrapup

Query Side and the Read Models

Queries

Query Handlers

Query Bus

Putting It All Together

Wrapup

Synchronizing the Write and the Read Models

Multiple Read Models

Synchronization Strategies

Wrapup

The Full Picture

The Timeline Use Case

Posting a Cheep

Command

Command Bus

Command Handler

Domain Event

Event Bus

Event Handler

Projection

Projection Bus

Projection Handler

Fetching the Timeline

Query

Query Bus

Query Handler

Wrapup

Optimizations and Edge Cases

Relying on Multiple Read Models

Incremental Projections

Race Conditions

Trouble with Events

Duplicated Messages

Missing Events

Dealing with Inconsistencies

Wrapup

CQRS and Event Sourcing

CQRS’ Biggest Challenge

Recreating State from Past Events

Introducing the Event Store

Changes in Repositories

Changes in Entities or Aggregates

Changes in Projections

Event Sourcing Tradeoffs

Wrapup

Demo Time

Getting Started

Starting the Application

Nothing Up My Sleeve

Signing Up New Authors

Consuming

NewAuthorSigned

Events

Following Other Authors

Consuming

FollowCommand

Commands

Verifying an Author’s Followers

Consuming

AuthorFollowed

Events

Posting Cheeps

Consuming

PostCheepCommand

Commands

Consuming

CheepPosted

Events

Consuming

AddCheepToTimelineProjection

Projections

Verifying an Author’s Timeline

Wrapup

The End

Bibliography

Guide

Begin Reading

Thanks to Vanessa, Valentina, and Gabriela: my love, my light, and my life. Thanks to Juan Luis, Pastora, Juan Lu, and Isa, my North Star. Thanks to Keyvan, Christian, Ricard, Álvaro, Jordi, and Eber, my inspiration. – Carlos

To my Elena, for being my North Star and my light in this second book, and for all your infinite support and love you give me each day of my life. Thanks to Carlos and Keyvan once again for making this book possible and always pushing forward. – Christian

My eternal gratitude to my wife Clara and my daughter Analía; plenty of the time invested in this book was theirs, and I’ll be forever indebted to them for their continuous support and encouragement. Thanks to my co-authors Carlos and Christian, my partners and friends in this incredible journey. You are an inspiration and bring out the best in me. – Keyvan

Foreword by Marco Pivetta

For many years, I’ve been talking about, preaching, and teaching CQRS and Event Sourcing principles to software engineers, architects, and industry newcomers. Carlos, Christian, and Keyvan have been on the same education front, introducing a whole generation of developers and software architects to the advantages, disadvantages, and possibilities offered by Domain-Driven Design and its related practices.

Every group of people involved in learning CQRS has been amazed by the doors it opens. However, don’t be fooled: Every system has flaws and overwhelming complexity, but mitigating them is part of the task of an engineer. If you decide to walk such a path, and if you walk it successfully, the resulting system is a pleasure to work with — from the application planning process, to its development, maintenance, and reliability.

When reading this book, you’ll find development approaches that you may already have seen and be familiar with. Additionally, you’ll also find new ways to deliver working software that encourage engaging discussion. The authors don’t fall into dogmatism and opinionated positions; instead, they offer up well-explained tradeoffs so that you can make your own informed decisions.

Take this book, learn from its contents, and discuss it with your peers: It’s a good resource for your projects. Once you’ve learned what’s in this book, you’ll be a much better software designer, and it’ll be up to you to invent new and better ways to implement CQRS. Enjoy the journey.

– Marco “Ocramius” Pivetta

Marco Pivetta, also known as “Ocramius,” is a software consultant working for Roave. He works on various open source PHP projects, and he often works on the architecture of highly complex PHP applications. He’s a core team member of the Doctrine Project, a popular PHP Object Relational Mapper. You can follow him on Twitter, contact him via email, read his blog, or see what he’s up to on GitHub.

Preface

Domain-Driven Design in PHP

In 2014, after two years of reading about and working with Domain-Driven Design, Carlos and Christian, friends and workmates, traveled to Berlin to participate in Vaughn Vernon’s Implementing Domain-Driven Design Workshop. The training was fantastic, and all the concepts that were swirling around in their minds before the trip suddenly became very real.

Around the same time, php[tek], an annual PHP conference, opened its call for papers, and Carlos sent one about Hexagonal Architecture. The organization rejected his talk. Months later, Eli White — of musketeers.me and php[architect] fame — got in touch with him. Eli was wondering if he was interested in writing an article about Hexagonal Architecture for the magazine php[architect]. In June 2014, Hexagonal Architecture with PHP was published in the magazine.

In late 2014, Carlos and Christian talked about extending the article and sharing all their knowledge of and experience in applying Domain-Driven Design in production. They were very excited about the idea behind the book: helping the PHP community delve into Domain-Driven Design from a practical approach. At that time, concepts such as Rich Domain Models and framework-agnostic Applications weren’t so prevalent in the PHP community. In December 2014, Carlos and Christian started to work on the already well-known Domain-Driven Design in PHP book.

Around the same time, in a parallel universe, Keyvan co-founded Funddy, a crowdfunding platform for the masses built on top of the concepts and building blocks of Domain-Driven Design. Domain-Driven Design proved itself effective in the exploratory process and modeling of building an early-stage startup like Funddy. It also helped handle the complexity of the company, with its constantly changing environment and requirements. After connecting with Carlos and Christian, they discussed the book and Keyvan proudly signed on as the third writer.

Together, we wrote the book we wanted to have when we started with Domain-Driven Design — full of examples, production-ready code, shortcuts, and recommendations based on our experiences of what worked and what didn’t for our respective teams. We arrived at Domain-Driven Design via its building blocks, which is why the book orbited around what are today known as Tactical Patterns. And in this book, you’ll learn how to use and implement them. In September 2016, after a couple of years of tough work Domain-Driven Design in PHP was finally published online on Leanpub. A year later, in 2017, the book became a physical reality via PackPub and Amazon.

Needless to say, we were heavily inspired by Vaughn Vernon’s Implementing Domain-Driven Design book (the Red Book), and Eric Evans’ original book, Domain-Driven Design: Tackling Complexity in the Heart of Software (the Blue Book). We can’t recommend these books enough.

Domain-Driven Design Acceptance Has Rapidly Grown

As Domain-Driven Design authors and early adopters, we’re thrilled to see how Domain-Driven Design has taken off, and how its building blocks and its philosophy have permeated the community and become standard. We love how modern architectures such as Hexagonal Architecture, Ports and Adapters, Onion Architecture, and Clean Architecture have empowered developers to build Applications that are easy to evolve, test, and maintain. It’s been pleasing to see the trend of using Domain Events as a communication pattern between different Applications and business boundaries.

Due to some characteristic limitations while scaling Hexagonal Architecture Applications, we thought it’d be a great idea to get deep into Greg Young’s work on CQRS, heavily inspired by Bertrand Meyer’s Command-Query Separation (CQS) principle. We highly recommend Greg’s workshops and courses on Domain Driven Design, CQRS, and Event Sourcing.

In 2017, Carlos presented the Buenosvinos Maturity Model at the Polycon and SymfonyCon Cluj conferences. This model describes the different maturity levels when architecting Applications:

Buenosvinos Maturity Model

With this model, you can self-assess in which Architectural Style you find yourself and determine what actions to take to move to the next level.

In our experience, companies successfully using Hexagonal Architecture experience lots of benefits against framework coupling or spaghetti code: better semantics and meaningful code, less coupling, and easier testability. However, we’ve seen that many companies experience limitations that aren’t that easy to solve — issues such as performance and dependency management at scale. Here’s where this book comes into play.

CQRS by Example

Four years have passed since our first publication. We established what we think is a solid ground for Domain-Driven Design building blocks and Hexagonal Architecture. It’s now time to explore how to solve the limitations some projects may face at scale. We think CQRS is the next natural step forward, and we want to guide you through it.

CQRS is usually discussed along with Event Sourcing, a pattern where the Application state is a Projection of the Domain Events that happen through its lifetime. Event Sourcing relies on having a stream of Domain Events to reconstitute state. Triggering Domain Events is a simple addition to operations that modify the state of the Application, such as Commands; however, querying the system now requires some unique mechanisms that aren’t that trivial to implement. We can say that in Event Sourced systems, CQRS is mandatory for generating the required information to be able to query later, but the opposite isn’t true. We can develop a CQRS system without Event Sourcing, so worry not: This book won’t cover Event Sourcing.

In this book, we’ll explore Hexagonal Architecture drawbacks, and we’ll dive into CQRS by exploring plenty of real examples you can use in your projects. Even though code examples are written in PHP, the patterns and techniques described in this book apply to any programming language and likely any paradigm you may be using.

We can’t thank you enough for purchasing this book and being an active contributor to Domain-Driven Design, Hexagonal Architecture, and CQRS!

Who Should Read This Book

If you’re a developer, architect, or tech lead, we highly recommend this book. It’ll provide you with some pretty interesting tools for your daily toolbox and may reveal an alternative architectural approach for your application. If you don’t have much experience, getting into CQRS and modern architectural patterns may prepare you for what’s to come throughout your career. For the average reader, understanding the benefits of CQRS and the boundaries between your framework and your Application may be crucial for writing code that’s easier to maintain in the real world (e.g. framework migrations, testing). Experienced readers will definitively have some fun exploring Projections and read layers to increase the performance of Applications.

Additionally, the book is loaded with tons of details and examples, such as how to properly design and implement all the building blocks of CQRS — including Commands, Command Handlers, Command Buses, Queries, Query Handlers, Query Buses, Domain Events, Event Buses, Projections, Read Thin Layers, and more.

Summary of Chapters

The book is arranged with each chapter exploring a separate tactical building block of CQRS. It also includes an introduction to CQRS, Domain-Driven Design, and the example project we’ll use throughout the book, Cheeper, which is a Twitter clone that’s experiencing some issues. Each section below outlines the questions that the corresponding chapter answers.

Chapter 1: CQRS and Domain-Driven Design

What is Domain-Driven Design? What role does it play in complex systems? Is it worth learning about and exploring? What are the main concepts a developer needs to know when jumping into it? How does CQRS relate to Domain-Driven Design?

Chapter 2: A Journey Toward CQRS

What’s the foundation of CQRS? What was the context in which CQRS was created? What problems does CQRS solve? In which scenarios is CQRS useful and in which ones does it not pay off?

Chapter 3: Anatomy of CQRS

What are the main building blocks of CQRS? What is the Command Side? What is the Query Side? What are the overall strategies to keep the Read Model and the Write Model in sync? What are some real use cases, their main components, and flows of information?

Chapter 4: Command Side and the Write Model

What is a Command? What about a Command Handler? Why are they important? What’s the role of the Command Bus? What are Async Commands and Sync Commands?

Chapter 5: Query Side and the Read Models

What is a Query? What is a Query Handler? Do we need a Query Bus? What is a Read Thin Layer? What are the properties of a good Read Model? How many Read Models can I have? What is a Projection?

Chapter 6: Synchronizing the Write and Read Models

What options do I have to sync the Write Model and the Read Models? Do I need to sync them? Can I use strategies other than messaging? Is messaging the best approach?

Chapter 7: The Full Picture

How can I put into practice all the previously learned concepts? How many asynchronous steps are needed for simple use cases? How many for complex ones?

Chapter 8: Optimizations and Edge Cases

How can I optimize the build time of Projections? What challenges will I face when dealing with Events? How can I recover from duplicate or lost messages?

Chapter 9: CQRS and Event Sourcing

What heuristics do I need to consider using CQRS? How do I move into Event Sourcing? What are the criteria to decide if I should stop at CQRS or move forward?

Chapter 10: Demo Time

How can I demo multiple use cases, understanding in detail what’s happening in every step? How do I interact with an Application? How do I consume synchronous and asynchronous Commands? How do I consume Events? How do I consume Projections?

Code, Typos, and Examples

There’s an organization at GitHub called DDD Shelf. In this organization, you’ll find Cheeper, a Twitter clone application used throughout the book to teach you all the concepts around CQRS. You’ll also find additional snippets and tools.

If you find any issue or fix or have a suggestion or comment while reading this book, you can open an issue in the CQRS By Example Book Issues repository. We fix them as they come in. If you’re interested, we encourage you to follow our projects and provide feedback.

Acknowledgements

First of all, we’d like to thank all our friends and family. Without their support, writing this book would’ve been an impossible task. You’re wonderful, and part of the success of this book is also yours.

It’s no surprise our design skills are quite limited. Our beautiful cover was crafted by our friend and master designer Carlos Tallón, and we owe him a huge thanks.

We are three Spaniards who wrote a book in English, so if you’d guess our English is far from perfect, you’d be correct. The final version of this book has been edited by a professional copy editor, Natalye Childress. She has done a great deal of work fixing typos, rewording our phrases, and rethinking the book structure. Thank you so much. Our book is far easier and more enjoyable to read now.

Thanks to Marco Pivetta for his foreword and feedback on the book. The book is now better thanks to his contributions.

A special mention to Greg Young: Your work has been an incredible source of information and inspiration for us.

Last but not least, we’d like to express our gratitude to all the people who have reported issues, made suggestions, and otherwise contributed to our GitHub repository. To all of you, thank you. You’ve helped us make this book better. More importantly, you’ve helped the community grow and helped other developers be better developers. Thanks to Mohammad Emran Hasan, Ashish K. Poudel, Eduardo Anton Santa-Maria, Mohamed Cherif Bouchelaghem, Jose Samonte, Ruben Calvo, Sami Jnih, Diego García, and David Navarro.

About the Authors

Carlos Buenosvinos

Carlos is an Extreme Programmer (XP) and DevOps with more than 20 years of experience in developing Web and Mobile Applications. For the last ten years, he has played various leading roles such as Tech Lead, VP of Engineering, and CTO. He has mentored engineering and product teams of up to 150 members in multiple different markets such as E-commerce, E-Learning, Payment Processing, Classifieds, and Recruiting Market.

As an employee and consultant, he has contributed to the success of start-ups and well-established brands. Some examples are SEAT, NewWork/XING, Atrápalo, GMV, PCComponentes, Cash Converters, Emagister, O2O, Opositatest, Techpump, Packlink, eBay, Lowpost, Vendo, Riplife, and many more.

He is the happy creator of Ansistrano, the most starred Ansible Galaxy role. He is also the author of the book Domain-Driven Design in PHP. He is also a conference speaker and organizer of the DevOps Barcelona Conference and the PHP Barcelona Conference.

His main areas of expertise are Agile Team Management (Scrum and Kanban), Best Development Practices (Extreme Programming, Domain-Driven Design, and Microservice Architectures), and Digital Transformation (Agile, XP, and DevOps).

You can follow him at Twitter, at his blog or at GitHub.

Christian Soronellas

Christian is an Extreme Programmer and has over 15 years of experience helping tech companies succeed from a broad variety of roles, from Software Engineer to CTO. He has helped companies such as Privalia, Emagister, Atrápalo, Enalquiler, PlanetaHuerto, PcComponentes or Opositatest. He is the author of the book Domain-Driven Design in PHP as well as a conference co-organizer of DevOps Barcelona Conference and PHP Barcelona Conference

You can follow him at Twitter or at GitHub.

Keyvan Akbary

Keyvan is an Engineering Leader and programmer with more than 15 years of experience crafting products customers love and helping teams succeed. He understands technology as a medium for providing value, not the end itself. He has a passion for Distributed Systems, Software fundamentals, SOLID principles, Clean Code, Design Patterns, Domain-Driven Design and, Testing; as well as being a sporadic Functional Programmer. For the last 7 years he has also focused on growing teams in high scaleup product companies, advocating for customer-centric product development, Extreme Programming, DevOps, Lean, and Kanban.

He has worked on countless projects as a freelancer, on video streaming at Youzee, tradesman marketplace at MyBuilder, in addition to founding his own crowdfunding startup Funddy, and leading FinTech teams at Wise. Currently, he is leading engineering in the ride-hailing space as Head of Engineering at Cabify.

He is also the author of “Domain-Driven Design in PHP” and “The Manager’s Manual”.

You can follow him at Twitter, at LinkedIn, at his blog or at GitHub.

CQRS and Domain-Driven Design

Command-Query Responsibility Segregation (CQRS) builds on top of the many concepts introduced in Domain-Driven Design (DDD), and both architectures have influenced one another. Although knowing Domain-Driven Design isn’t required to understand the contents of this book, we suggest reading about it beforehand because it’ll help you out in your journey toward learning and understanding CQRS. In this chapter, we’ll briefly introduce you to the topic. If you’re already familiar with Domain-Driven Design, feel free to skip to the next chapter.

What’s All the Fuss About?

Domain-Driven Design is an approach that helps us succeed in understanding, designing, and building software models that solve complex business problems. The key elements are Domain, Model, and Software. Let’s start by reviewing them.

A Domain is a sphere of knowledge or activity. In the book Domain-Driven Design: Tackling Complexity in the Heart of Software, author Eric Evans uses a real example of a Cargo Shipping Domain. He deals with ships transporting goods, delayed arrivals, routing changes, overbooked capacity, and many more complex problems. Meanwhile, in the book Implementing Domain-Driven Design, author Vaughn Vernon makes a case for the Agile Project Management Domain. He deals with agile projects, backlogs, estimates, commitments, project forums, team members, etc. Both of these examples illustrate how —whether you’re working for a company or on your own — with Domain-Driven Design, your current project tries to create solutions to problems in a specific Domain.

A Model is a system of abstractions that describes selected aspects of a Domain and can be used to solve problems related to that Domain. A Model distills knowledge and assumptions about a Domain. One example of a Model is the well-known map of the world used to teach geography at schools. Originally, it was designed for navigators. In such a Domain, the map worked perfectly for going from point A to point B. Orientation, distances, and angles always matched — and this was because of a mathematical approach called the Mercator projection. The Mercator projection is a convenient cylindrical map Projection that’s widely used for teaching purposes. The problem with it is that it isn’t accurate, as countries appear bigger than they actually are the more they move away from the equator. As such, in the Domain of geography, this particular Model isn’t so useful.

What about Software? If you’re reading this book, there’s no need to explain what that is. However, you should know that Domain-Driven Design provides Developers with strategic and tactical modeling tools to aid in designing high-quality software that meets their business goals.

If you want to learn more about strategic patterns and Domain-Driven Design, you should read Domain-Driven Design Distilled by Vaughn Vernon or Domain-Driven Design Reference: Definitions and Pattern Summaries by Eric Evans.

More importantly, Domain-Driven Design is not about technology. Instead, it’s about developing knowledge around business and using technology to provide value. Only once you’re capable of understanding the industry your company works within will you be able to participate in the software model discovery process to produce a common business language and understanding — otherwise known as the Ubiquitous Language.

Why Domain-Driven Design Matters

Software isn’t about just code. If you think about it, code is rarely the end goal of our profession. Rather, it’s merely the medium for solving business problems. That said, why does it have to speak a different language than a business?

Domain-Driven Design emphasizes making sure a business and its software speak the same language. Once that occurs, barriers to communication are removed, and there’s no longer a need for translation or tedious syncing. Furthermore, the information doesn’t get lost. In this way, everyone — not just coders — contributes to discovering the Business Domain, and in turn, the resulting software is the only truth for the common language.

Domain-Driven Design also provides a framework for Strategic Design and Tactical Design — strategic to pinpoint the most critical areas to develop based on business value, and tactical to build a working Domain Model of battle-tested building blocks and patterns.

The Three Pillars of Domain-Driven Design

Domain-Driven Design is an approach for delivering software, and it’s based on three pillars, outlined here.

Ubiquitous Language — Domain Experts and software Developers work together to build a common language for the business areas being developed. There’s no us versus them; it’s always us. Developing software is a business investment and not just a cost, and the effort involved in building the Ubiquitous Language helps spread deep Domain insight among all team members.Strategic Design — Domain-Driven Design addresses the strategy behind the direction of the business and not just the technical aspects. It helps define the internal relationships and early warning feedback systems. On the technical side, Strategic Design protects each business service by encouraging service-oriented architecture best practices.Tactical Design — Domain-Driven Design provides the tools and the building blocks for iterative software deliverables. Tactical Design tools produce software that’s not only correct, but also testable and less error prone.

Ubiquitous Language

The Ubiquitous Language is the common business language, and it has a meaning within the limits of a specific business context. This specific context is known as a Bounded Context, which is a pattern relating to Strategic Design. These two concepts are central to Domain-Driven Design.

In Terms of Context

For now, think of a Bounded Context as a conceptual boundary around a system, while the Ubiquitous Language inside a boundary has a specific contextual meaning. Meanwhile, concepts outside of this context can have different meanings.

So, how to find, explore, and capture this precise language?

Identify key business processes, their inputs, and their outputs.Create a glossary of terms and definitions.Capture important software concepts with some kind of documentation.Share and expand upon the collected knowledge with the rest of the team (Developers and Domain Experts).

Since Domain-Driven Design was born, new techniques for improving the process of building the Ubiquitous Language have emerged. The most important one, which is used regularly now, is EventStorming.

EventStorming

Alberto Brandolini explains EventStorming and its advantages in a blog post, and he does it far more succinctly than we could:

EventStorming is a workshop format for quickly exploring complex business domains.

It is powerful: it has allowed me and many practitioners to come up with a comprehensive model of complete business flow in hours instead of weeks.It is engaging: the whole idea is to bring people with the questions and people who know the answer in the same room and to build a model together.It is efficient: the resulting model is perfectly aligned with a Domain-Driven Design implementation style (particularly fitting an Event Sourcing approach) and allows for a quick determination of Context and Aggregate boundaries.It is easy: the notation is ultra-simple. No complex UML might cut off participants from the heart of the discussion.It is fun: I always had a great time leading the workshops, people are energized and deliver more than they expected. The right questions arise, and the atmosphere is the right one.

If you want to know more about EventStorming, check out Brandolini’s book, Introducing EventStorming.

Strategic Design

To provide a general overview of the strategic side of Domain-Driven Design, we’ll use an approach from Jimmy Nilsson’s book, Applying Domain-Driven Design and Patterns. Consider two different spaces: the problem space and the solution space.

In the problem space, Domain-Driven Design uses Domains and Subdomains to group and organize what companies want to solve. In the case of an online travel agency (OTA), the problem is about dealing with things like purchasing plane tickets and booking hotels. Such a Domain can be organized into different Subdomains such as Pricing, Inventory, User Management, etc.

In the solution space, Domain-Driven Design provides two patterns: Bounded Contexts and Context Maps. The goal is to define how to provide an implementation to all the identified Subdomains by defining their interactions and the details of those interactions. Continuing with the OTA example, each of the Subdomains will be solved with a Bounded Context implementation — for example, consider a custom web Application developed by a team for the Pricing Management Subdomain, and an off-the-shelf solution for the User Management Subdomain. The Context Map will show how each Bounded Context is related to the rest. Inside the Context Map, we can see what type of relation two Bounded Contexts have (e.g. customer-supplier, partners). The ideal approach is to have each Subdomain implemented by one Bounded Context, but that’s not always possible.

In terms of implementation, when following Domain-Driven Design, you’ll end up with distributed architectures. As you may already know, distributed architectures are more complex than monolithic ones, so why is this approach attractive, especially for big and complex companies? Is it really worth it?

Well, distributed architectures are proven to increase overall company productivity because they define boundaries for your product that can be developed by focused teams. So note that if your Domain — the problem you need to solve — isn’t complex, applying the strategical part of Domain-Driven Design can add unnecessary overhead and slow down your development speed. As such, it’s important to make sure that Domain-Driven Design is what your business really needs.

If you want to know more about the strategic part of Domain-Driven Design, you should take a look at the first three chapters of Vaughn Vernon’s book, Implementing Domain-Driven Design, or the book Domain-Driven Design: Tackling Complexity in the Heart of Software by Eric Evans — both of which specifically focus on this aspect.

Tactical Design

Once the strategic part is clear, it’s time to jump into the implementation. Domain-Driven Design identifies a set of Design Patterns and Architectural Styles that help us pull our Domain Model into code. These building blocks are useful when writing code as part of a specific Bounded Context. In terms of software architecture, each Bounded Context can be implemented as a single service, an Application, or a set of microservices that communicate with each other. When it comes to implementing one of these services, two main Architectural Styles fit pretty well with Domain-Driven Design: Hexagonal Architecture — also known as Ports and Adapters — and Event Sourcing with CQRS.

Command-Query Responsibility Segregation (CQRS) is one of the suggested Architectural Styles in Domain-Driven Design, together with Hexagonal Architecture and Event Sourcing. CQRS is mostly used alongside Event Sourcing; however, it can be used independent of it.

Moving from the architecture to a more detailed implementation, Domain-Driven Design focuses on a set of Design Patterns that support the Domain Model in code. Using these patterns will make it easier to write the code as the Ubiquitous Language of the Domain. Let’s take a closer look:

Value Objects — Objects that describe, measure, or quantify. They’re identified by the values they contain. Examples may be an email address, a product height, a quantity of money, or a price.Entities — Objects that represent the main elements in a Domain. They’re identified by a unique ID and contain the main business logic of an Application. Examples may be a user, a product, an order, or an invoice.Factories — Objects that build other objects in the Domain Model.Repositories — Objects that fetch and store Entities.Domain Services — Objects that contain business logic that isn’t related to a specific Entity — for example, a payment service. Domain Events — Objects that represent things that happen in a Domain that are interesting for the business. Examples may be OrderPlaced, UserSignedIn, or DataExportRequested.Aggregates — Objects like Entities that contain other Entities that are required to be persisted and retrieved in the same transaction. For example, an invoice with all the invoice lines, taxes, and discounts.Application Services or Command Handlers — Objects that represent the high-level use cases of an Application and orchestrate the steps to fulfill the business requirements. Examples may include RegisterNewCustomer or DisableProduct.

If you want to know more about the tactical part of Domain-Driven Design, you should take a look at our first book, Domain-Driven Design in PHP, or the second half of Vaughn Vernon’s book, Implementing Domain-Driven Design — both of which specifically focus on this aspect.

Considering Domain-Driven Design

Domain-Driven Design isn’t a silver bullet; as with everything in software, it depends on the context. As a rule of thumb, use it to simplify your Domain, but never to add more complexity.

If your Application is data-centric and your use cases mainly manipulate rows in a database and perform CRUD operations — that is, Create, Read, Update, and Delete — you don’t need Domain-Driven Design. Instead, the only thing your company needs is a fancy user interface (UI) in front of your database.

If your Application has less than 30 use cases, it might be simpler to use a framework like Symfony or Laravel to handle your business logic.

However, if your Application has more than 30 use cases, your system may be moving toward the dreaded “Big Ball of Mud.” If you know for sure your system will grow in complexity, you should consider using Domain-Driven Design to fight that complexity.

If you know your Application is going to grow and is likely to change often, Domain-Driven Design will help in managing the complexity and when refactoring your Model over time.

If you don’t understand the Domain you’re working on because it’s new and nobody has invested in a solution before, this might mean it’s complex enough for you to start applying Domain-Driven Design. In this case, you’ll need to work closely with Domain Experts to get the Models right.

The Tricky Parts

Applying Domain-Driven Design isn’t easy. It requires time and effort to get around the Business Domain and terminology. It also requires a lot of research, and as mentioned above, you’ll need to involve Domain Experts in the process too. Such a commitment will require an open and healthy continuous conversation to model spoken language in the software. On top of that, you’ll have to make an effort to think in the Ubiquitous Language and understand the relationships between objects before getting into the technical implementation of things.

Wrapup