Domain Event - The Hidden Gem of DDD

37
The Domain Event The Hidden Gem of DDD

Transcript of Domain Event - The Hidden Gem of DDD

Page 1: Domain Event - The Hidden Gem of DDD

The Domain Event!The Hidden Gem of DDD

Page 2: Domain Event - The Hidden Gem of DDD

Henrik Møller RasmussenFounder and CTO

The digital daycare

Page 3: Domain Event - The Hidden Gem of DDD

The digital daycare

6 institutions!~1.000 children

Page 4: Domain Event - The Hidden Gem of DDD

Vaughn Vernon: Implementing Domain-Driven DesignEric Evans: Domain-Driven Design: Tackling …

2003 Theoretical

2013!Practical

Domain-Driven Design

Page 5: Domain Event - The Hidden Gem of DDD

Do you DDD?

• Domain Model • Repository • Ubiquitous language • Domain Service • Application Service • Bounded context • Context map • Domain Event • Anti Corruption Layer • And many more…

Page 6: Domain Event - The Hidden Gem of DDD

class Product { ! protected $title; ! protected $price; ! public function setPrice($price) { // .. } ! public function getPrice() { // .. } ! public function setTitle($title) { // .. } ! public function getTitle() { // .. } !}

Is this your domain model?

Page 7: Domain Event - The Hidden Gem of DDD

class ProductController { ! public function addToBasketAction($product) { if ($product->getInStock() <= 0) { $this->redirect(); } ! // Add to basket } }

Where's your business logic?

Page 8: Domain Event - The Hidden Gem of DDD

Let’s build a shop..

Page 9: Domain Event - The Hidden Gem of DDD

Models, Views and Controllers

• Domain models grow into huge classes

• Hard to reason about (mental model)

• Domain models and relations are designed for viewing purposes

• Everything is extremely coupled

• “Big ball of mud”

Package: My.Shop

Page 10: Domain Event - The Hidden Gem of DDD

Proper DDD

Page 11: Domain Event - The Hidden Gem of DDD

Product

CategoryInvoice

Order

EmailCustomer

Reporting

Searching

Inventory

Shipping

Page 12: Domain Event - The Hidden Gem of DDD

Product

CategoryInvoice

Order

EmailCustomer

Reporting

Searching

Inventory

Shipping

Page 13: Domain Event - The Hidden Gem of DDD

Catalog

Inventory

Billing

Search

Reporting

Bounded Contexts / Modules

Page 14: Domain Event - The Hidden Gem of DDD

Catalog

Domain models

Product Category

RepositoriesCatalogService (Application Service)

Page 15: Domain Event - The Hidden Gem of DDD

Inventory

Domain models

Product

RepositoriesInventoryService (Application Service)

Page 16: Domain Event - The Hidden Gem of DDD

There will be more than one class representing a product

Page 17: Domain Event - The Hidden Gem of DDD

• Small models / modules / bounded contexts

• Easy to reason about

• Easy to test

• Loosely coupled

Benefits

Page 18: Domain Event - The Hidden Gem of DDD

Catalog

Inventory

Billing

Search

Reporting

Communication

Page 19: Domain Event - The Hidden Gem of DDD

IntroducingThe Domain Event

Page 20: Domain Event - The Hidden Gem of DDD

So what is a domain event?

• It’s a message …

• .. implemented as a class

• .. published to “the world”

• It’s past tense (e.g. OrderCompletedEvent)

• It’s transactionally coupled to your domain model

• It’s asynchronous

Page 21: Domain Event - The Hidden Gem of DDD

class OrderCompletedEvent { ! public $orderId; ! public $amount; ! public $completedAt; ! public $customerId; !}

Example

Page 22: Domain Event - The Hidden Gem of DDD

class Order { ! public function complete() { $this->completedAt = new \DateTime(); ! $this->eventService->publish( new OrderCompletedEvent(…) ); } !}

Publishing event

Page 23: Domain Event - The Hidden Gem of DDD

Catalog

Inventory

Search

BillingM

essa

ge B

us

EXAMPLE: Order Completed

Page 24: Domain Event - The Hidden Gem of DDD

Why not use signal/slots for that?

Page 25: Domain Event - The Hidden Gem of DDD

1. Customer places order

2. Signal / Slot trigger a foreign context tosend the order confirmation via email

3. Something breaks during persistence of the order.

What now?

Signal / Slot example

Page 26: Domain Event - The Hidden Gem of DDD

START TRANSACTION!UPDATE order … INSERT INTO event_store … COMMIT!!!If this succeeds the event is published to the message bus

Transactionally safe domain events

Page 27: Domain Event - The Hidden Gem of DDD

Catalog

Inventory

Search

BillingM

essa

ge B

us

EXAMPLE: InStock is updated in the inventory

Page 28: Domain Event - The Hidden Gem of DDD

Catalog

Inventory

Search

BillingM

essa

ge B

us

EXAMPLE: Product description updated in the catalog

Page 29: Domain Event - The Hidden Gem of DDD

Benefits of using domain events

• Allows you to integrate bounded contexts with minimal coupling and dependencies.

• Add features to the system with no changes to existing code.

• Get a more responsive system since a lot of functionality is handled asynchronous.

• Get a more robust system. Easier to build fault tolerant system. (Fx. problems with third party services like payment gateways etc.)

Page 30: Domain Event - The Hidden Gem of DDD

UI

Catalog

Inventory

Billing

Search

Reporting

Page 31: Domain Event - The Hidden Gem of DDD
Page 32: Domain Event - The Hidden Gem of DDD

Is it simple to maintain?!Does it perform?!

Yes!No!

(Come see my talk tomorrow about CQRS)

Is it simple to build?! Yes!

Page 33: Domain Event - The Hidden Gem of DDD

Let’s talk Flow

Page 34: Domain Event - The Hidden Gem of DDD

What is a bounded context?

Package?!Subdirectory?!

Its own Flow installation?!Another system?

Could be any of above as long as they are independent and only integrate through domain events (or service calls).

!No sharing of domain models etc.

Page 35: Domain Event - The Hidden Gem of DDD

How do I get started?

https://github.com/agitso/event

• Uses Doctrine’s PostFlush event listener to hook intoDoctrine after persistence and handle domain events.

• The same technique is used in Famly, where we havecurrently handled +500.000 domain events

Page 36: Domain Event - The Hidden Gem of DDD

Recap

• Split your system into smaller modules / bounded contexts

• Put your business logic into the domain models

• Integrate modules with Domain Events (use application service callsfor synchronous interactions).

• Use controllers to orchestrate the views - that is fetch datafrom Application Services and assign to views and similar.NO BUSINESS LOGIC HERE.

Page 37: Domain Event - The Hidden Gem of DDD

Henrik Møller [email protected] Twitter: @heinodk IRC: Come join us at #ddd

The digital daycare