SlideShare a Scribd company logo
Domain Driven 
Design 
Using Laravel 
by 
Waqar Alamgir
Managing 
Complexity 
AKA Engineering
Functional 
Requirement
Lets Look at some Concepts 
1. MVC Design Pattern 
2. Entities 
3. Active Records
MVC Design 
Pattern
Entities 
“Many objects are found 
fundamentally by their 
attributes but rather by a 
thread of continuity and 
identity” – Eric Evans
Person 
Waqar Alamgir 
Age 26 
From Karachi 
Waqar Alamgir 
Age 26 
From Karachi
Active Records
Person 
Waqar Alamgir 
Age 26 
From Karachi 
Waqar Alamgir 
Age 26 
From Karachi 
ID NAME AGE LOCATION 
1 Waqar Alamgir 26 Karachi 
2 Waqar Alamgir 26 Karachi
Laravel Framewrok 
Laravel is a free, open source PHP web application 
framework, designed for the development of model–view– 
controller (MVC) web applications. Laravel is listed as 
the most popular PHP framework in 2013. 
Eloquent ORM (object-relational mapping) is an advanced 
PHP implementation of the active record pattern. 
Better Routing. 
Restful controllers provide an optional way for separating 
the logic behind serving HTTP GET and POST requests. 
Class auto loading. 
Migrations provide a version control system for database 
schemas.
That’s not DDD
Philosophy 
In building large scale web applications MVC 
seems like a good solution in the initial 
design phase. However after having built a 
few large apps that have multiple entry 
points (web, cli, api etc) you start to find 
that MVC breaks down. Start using Domain 
Driven Design.
A Common Application 
PRESENTATION LAYER 
Controllers 
Artisan Commands 
Queue Listeners 
SERVICE LAYER 
Sending Email 
Queuing up Jobs 
Repository Implementations 
COMMANDS / COMMAND BUS 
DOMAIN 
Entities 
Repository Interface
What is Command 
Meat of the application 
Controller 
Artisan Command 
Queue Worker 
Whatever
What is Command 
Meat of the application 
Commands 
i.e. Register Member 
Command
What is Command 
Meat of the application 
Commands 
i.e. Register Member 
Command
Advantages 
1. No business policy in your controller 
2. Your code shows intent 
3. A single dedicated flow per user case 
4. A single point of entry per user case 
5. Easy to see which use cased are implemented
Register Command 
class RegisterMemberCommand 
{ 
public $displayName; 
public $email; 
public $password; 
public function __construct($displayName , $email , 
$password) 
{ 
$this->displayName = $displayName; 
$this->email = $email; 
$this->password = $password; 
} 
}
Register Command 
class RegisterMemberCommand 
{ 
public $displayName; 
public $email; 
public $password; 
public function __construct($displayName , $email , 
$password) 
{ 
$this->displayName = $displayName; 
$this->email = $email; 
$this->password = $password; 
} 
}
The Final Destination 
Register Member 
Handler 
Register Member 
Command 
Meat of the application
The Final Destination 
Register Member 
Handler 
Register Member 
Command 
Meat of the application 
Command Bus
Implementing 
Command Bus
class ExecutionCommandBus implements CommandBus 
{ 
private $container; 
private $mapper; 
public function __construct(Container $container , Mapper 
$mapper) 
{ 
$this->container = $container; 
$this->mapper = $mapper; 
} 
public function execute($command) 
{ 
$this->getHandler($command)->handle($command); 
} 
public function getHandler($command) 
{ 
$class = $this->mapper- 
>getHandlerClassFor($command); 
return $this->container->make($class); 
} 
}
How Does The 
Mapper Know?
One Handle Per 
Command
Let’s Look at 
very basic 
Register Member 
Command 
*with out any sequence*
class RegisterMemberHandler implements Handler 
{ 
private $memberRepository; 
public function __construct(MemberRepository 
$memberRepository) 
{ 
$this->memberRepository = $memberRepository; 
} 
public function handle($command) 
{ 
$member = Member::register( 
$command->displayName, 
$command->email, 
$command->password 
); 
$this->memberRepository->save($member); 
} 
}
class Member extends Eloquent 
{ 
public static function register($displayName , $email , 
$password) 
{ 
$member = new static([ 
‘display_name’ => $displayName, 
‘email’ => $email, 
‘password’ => $password 
]); 
return $member; 
} 
}
Flow Review
Flow Review 
PRESENTATION 
LAYER 
Command 
SERVICE 
LAYER 
COMMAND BUS Command Handler 
DOMAIN 
Entities 
Repositories
Simple Sequence
Simple Sequence 
Member Registers 
Subscribe to Mail 
Chimp 
Send Welcome Email 
Queue up 7 Day Email
Domain Events 
Trigger 
Listeners 
Raise Event 
Typical PUB-SUB pattern 
Dispatch Event
A Common Application 
PRESENTATION LAYER 
Controllers 
Artisan Commands 
Queue Listeners 
SERVICE LAYER 
Sending Email 
Queuing up Jobs 
Repository Implementations 
COMMANDS / COMMAND BUS 
Event Dispatcher 
DOMAIN 
Entities 
Repository Interface 
Domain Events
Events/ Listener 
Breakdown 
Member Registers 
Subscribe to Mail 
Chimp 
Send Welcome Email 
Queue up 7 Day Email
class MemberRegistered 
{ 
public $member; 
public function __construct(Member $member) 
{ 
$this->member = $member; 
} 
} 
class SendWelcomeEmail implements Listener 
{ 
public function handle($event) 
{ 
Mailer ::Queue(…); 
} 
}
Throwing Domain 
Events
class EventGenerator 
{ 
protected $pendingEvents = []; 
public function raise($event) 
{ 
$this->pendingEvents = $event; 
} 
public function releaseEvents() 
{ 
$events = $this->pendingEvents; 
$this->pendingEvents = [] ; 
return $events; 
} 
}
class Member extends Eloquent 
{ 
use EventGenerator ; 
public static function register($displayName , $email , 
$password) 
{ 
$member = new static([ 
‘display_name’ => $displayName, 
‘email’ => $email, 
‘password’ => $password 
]); 
$member->raise(new MemberRegistered($member)) ; 
return $member; 
} 
}
Interface Dispatcher 
{ 
public function addListener($eventName , Listener 
$listener) ; 
public function dispatch($events) ; 
} 
// Register Listeners 
$dispatcher = new Dispatcher() ; 
$dispatcher-> addListener(‘MemberRegistered’ , new 
SubscribeToMailchimp) ; 
$dispatcher-> addListener(‘MemberRegistered’ , new 
SendWelcomeEmail) ; 
$dispatcher-> addListener(‘MemberRegistered’ , new 
SendOneWeekEmail) ;
class RegisterMemberHandler implements Handler 
{ 
private $memberRepository; 
private $dispatcher; 
public function __construct(MemberRepository 
$memberRepository , Dispatcher $dispatcher) 
{ 
$this->memberRepository = $memberRepository; 
$this-> dispatcher = $dispatcher ; 
} 
public function handle($command) 
{ 
$member = Member::register( 
$command->displayName, $command->email, 
$command->password 
); 
$this->memberRepository->save($member); 
$this->dispatcher->dispatch($member-> 
releaseEvents()) ; 
} 
}
More Information 
About DDD 
Domain-Driven Design: Tackling 
Complexity in the Heart of 
Software - Eric Evans 
Implementing Domain-Driven 
Design- Vaughn Vernon
Thank You! 
Have more questions? 
Email: walamgir@folio3.com 
Twitter: @wajrcs

More Related Content

PDF
Cypress-vs-Playwright-Rematch-Applitools.pdf
Applitools
 
PDF
Performance Testing using Real Browsers with JMeter & Webdriver
BlazeMeter
 
PPTX
Token Authentication in ASP.NET Core
Stormpath
 
PDF
Webinar - Unbox GitLab CI/CD
Annie Huang
 
PPTX
Introduction to Firebase
Mustafa Şenel
 
PDF
Git Tutorial | Git Basics - Branching, Merging, Rebasing | Learn Git | DevOps...
Edureka!
 
PDF
Spring Framework - Spring Security
Dzmitry Naskou
 
PPT
Postman.ppt
ParrotBAD
 
Cypress-vs-Playwright-Rematch-Applitools.pdf
Applitools
 
Performance Testing using Real Browsers with JMeter & Webdriver
BlazeMeter
 
Token Authentication in ASP.NET Core
Stormpath
 
Webinar - Unbox GitLab CI/CD
Annie Huang
 
Introduction to Firebase
Mustafa Şenel
 
Git Tutorial | Git Basics - Branching, Merging, Rebasing | Learn Git | DevOps...
Edureka!
 
Spring Framework - Spring Security
Dzmitry Naskou
 
Postman.ppt
ParrotBAD
 

What's hot (20)

PPTX
Blazor
Ed Charbeneau
 
PDF
Clean architectures with fast api pycones
Alvaro Del Castillo
 
PPTX
Maven tutorial
Dragos Balan
 
PDF
Cypress-vs-Playwright: Let the Code Speak
Applitools
 
PDF
Software Design Patterns in Laravel by Phill Sparks
Phill Sparks
 
PPTX
Gradle
Jadson Santos
 
PPTX
Introduction to Maven
Mindfire Solutions
 
PDF
Introduction to Docker
Aditya Konarde
 
PDF
Workshop 4: NodeJS. Express Framework & MongoDB.
Visual Engineering
 
PPTX
Maven ppt
natashasweety7
 
PDF
글로벌 게임 플랫폼에서 무정지, 무점검 서버 개발과 운영 사례
if kakao
 
PPTX
Google Firebase Presentation
Aeni Patel
 
PDF
An Introduction of Node Package Manager (NPM)
iFour Technolab Pvt. Ltd.
 
PPTX
Docker: From Zero to Hero
fazalraja
 
PDF
ECMAScript 6 from an Attacker's Perspective - Breaking Frameworks, Sandboxes,...
Mario Heiderich
 
PDF
Service Discovery 101
Stefan Achtsnit
 
PDF
マルチテナント環境における WebLogic Server 管理
Masa Sasaki
 
ODP
Automating OWASP ZAP - DevCSecCon talk
Simon Bennetts
 
PDF
Python for Linux System Administration
vceder
 
PPTX
Introducing Swagger
Tony Tam
 
Clean architectures with fast api pycones
Alvaro Del Castillo
 
Maven tutorial
Dragos Balan
 
Cypress-vs-Playwright: Let the Code Speak
Applitools
 
Software Design Patterns in Laravel by Phill Sparks
Phill Sparks
 
Introduction to Maven
Mindfire Solutions
 
Introduction to Docker
Aditya Konarde
 
Workshop 4: NodeJS. Express Framework & MongoDB.
Visual Engineering
 
Maven ppt
natashasweety7
 
글로벌 게임 플랫폼에서 무정지, 무점검 서버 개발과 운영 사례
if kakao
 
Google Firebase Presentation
Aeni Patel
 
An Introduction of Node Package Manager (NPM)
iFour Technolab Pvt. Ltd.
 
Docker: From Zero to Hero
fazalraja
 
ECMAScript 6 from an Attacker's Perspective - Breaking Frameworks, Sandboxes,...
Mario Heiderich
 
Service Discovery 101
Stefan Achtsnit
 
マルチテナント環境における WebLogic Server 管理
Masa Sasaki
 
Automating OWASP ZAP - DevCSecCon talk
Simon Bennetts
 
Python for Linux System Administration
vceder
 
Introducing Swagger
Tony Tam
 
Ad

Viewers also liked (9)

PPTX
Implementing DDD Concepts in PHP
Steve Rhoades
 
PPTX
Onion Architecture
matthidinger
 
PPTX
Domain Driven Design Through Onion Architecture
BoldRadius Solutions
 
PPTX
Applying Domain-Driven Design to APIs and Microservices - Austin API Meetup
LaunchAny
 
PDF
API Design Methodology - Mike Amundsen, Director of API Architecture, API Aca...
CA API Management
 
PDF
The Architecture of an API Platform
Johannes Ridderstedt
 
PDF
Domain Driven Design
Nikolay Vasilev
 
PDF
Api architectures for the modern enterprise
CA API Management
 
PPTX
Designing APIs and Microservices Using Domain-Driven Design
LaunchAny
 
Implementing DDD Concepts in PHP
Steve Rhoades
 
Onion Architecture
matthidinger
 
Domain Driven Design Through Onion Architecture
BoldRadius Solutions
 
Applying Domain-Driven Design to APIs and Microservices - Austin API Meetup
LaunchAny
 
API Design Methodology - Mike Amundsen, Director of API Architecture, API Aca...
CA API Management
 
The Architecture of an API Platform
Johannes Ridderstedt
 
Domain Driven Design
Nikolay Vasilev
 
Api architectures for the modern enterprise
CA API Management
 
Designing APIs and Microservices Using Domain-Driven Design
LaunchAny
 
Ad

Similar to Domain Driven Design using Laravel (20)

PPTX
Laravel for Web Artisans
Raf Kewl
 
PDF
What's New In Laravel 5
Darren Craig
 
PDF
Doctrine For Beginners
Jonathan Wage
 
PDF
Osiąganie mądrej architektury z Symfony2
3camp
 
PDF
Dependency Injection
Alena Holligan
 
PDF
Symfony2 - from the trenches
Lukas Smith
 
PPT
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf Conference
 
PDF
The IoC Hydra - Dutch PHP Conference 2016
Kacper Gunia
 
PDF
Symfony2 from the Trenches
Jonathan Wage
 
PDF
Intro to Laravel 4
Singapore PHP User Group
 
PDF
What is DDD and how could it help you
Luis Henrique Mulinari
 
PDF
Decoupling with Design Patterns and Symfony2 DIC
Konstantin Kudryashov
 
PDF
symfony on action - WebTech 207
patter
 
PDF
Laravel 5 In Depth
Kirk Bushell
 
PDF
The IoC Hydra
Kacper Gunia
 
PDF
関西PHP勉強会 php5.4つまみぐい
Hisateru Tanaka
 
PDF
Domain-driven Design in PHP and Symfony - Drupal Camp Wroclaw!
Kacper Gunia
 
PPTX
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
arcware
 
PDF
Beyond symfony 1.2 (Symfony Camp 2008)
Fabien Potencier
 
PDF
Build powerfull and smart web applications with Symfony2
Hugo Hamon
 
Laravel for Web Artisans
Raf Kewl
 
What's New In Laravel 5
Darren Craig
 
Doctrine For Beginners
Jonathan Wage
 
Osiąganie mądrej architektury z Symfony2
3camp
 
Dependency Injection
Alena Holligan
 
Symfony2 - from the trenches
Lukas Smith
 
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf Conference
 
The IoC Hydra - Dutch PHP Conference 2016
Kacper Gunia
 
Symfony2 from the Trenches
Jonathan Wage
 
Intro to Laravel 4
Singapore PHP User Group
 
What is DDD and how could it help you
Luis Henrique Mulinari
 
Decoupling with Design Patterns and Symfony2 DIC
Konstantin Kudryashov
 
symfony on action - WebTech 207
patter
 
Laravel 5 In Depth
Kirk Bushell
 
The IoC Hydra
Kacper Gunia
 
関西PHP勉強会 php5.4つまみぐい
Hisateru Tanaka
 
Domain-driven Design in PHP and Symfony - Drupal Camp Wroclaw!
Kacper Gunia
 
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
arcware
 
Beyond symfony 1.2 (Symfony Camp 2008)
Fabien Potencier
 
Build powerfull and smart web applications with Symfony2
Hugo Hamon
 

Recently uploaded (20)

PDF
WatchTraderHub - Watch Dealer software with inventory management and multi-ch...
WatchDealer Pavel
 
PPTX
AI-Ready Handoff: Auto-Summaries & Draft Emails from MQL to Slack in One Flow
bbedford2
 
PPTX
slidesgo-unlocking-the-code-the-dynamic-dance-of-variables-and-constants-2024...
kr2589474
 
PDF
Salesforce Implementation Services Provider.pdf
VALiNTRY360
 
PPTX
Odoo Integration Services by Candidroot Solutions
CandidRoot Solutions Private Limited
 
PDF
Download iTop VPN Free 6.1.0.5882 Crack Full Activated Pre Latest 2025
imang66g
 
PDF
Immersive experiences: what Pharo users do!
ESUG
 
PPTX
Web Testing.pptx528278vshbuqffqhhqiwnwuq
studylike474
 
PDF
Summary Of Odoo 18.1 to 18.4 : The Way For Odoo 19
CandidRoot Solutions Private Limited
 
PPTX
Visualising Data with Scatterplots in IBM SPSS Statistics.pptx
Version 1 Analytics
 
PDF
Using licensed Data Loss Prevention (DLP) as a strategic proactive data secur...
Q-Advise
 
PPTX
classification of computer and basic part of digital computer
ravisinghrajpurohit3
 
PPTX
Role Of Python In Programing Language.pptx
jaykoshti048
 
PPTX
The-Dawn-of-AI-Reshaping-Our-World.pptxx
parthbhanushali307
 
PDF
10 posting ideas for community engagement with AI prompts
Pankaj Taneja
 
PDF
On Software Engineers' Productivity - Beyond Misleading Metrics
Romén Rodríguez-Gil
 
PDF
Protecting the Digital World Cyber Securit
dnthakkar16
 
PDF
New Download FL Studio Crack Full Version [Latest 2025]
imang66g
 
PPTX
Contractor Management Platform and Software Solution for Compliance
SHEQ Network Limited
 
PDF
An Experience-Based Look at AI Lead Generation Pricing, Features & B2B Results
Thomas albart
 
WatchTraderHub - Watch Dealer software with inventory management and multi-ch...
WatchDealer Pavel
 
AI-Ready Handoff: Auto-Summaries & Draft Emails from MQL to Slack in One Flow
bbedford2
 
slidesgo-unlocking-the-code-the-dynamic-dance-of-variables-and-constants-2024...
kr2589474
 
Salesforce Implementation Services Provider.pdf
VALiNTRY360
 
Odoo Integration Services by Candidroot Solutions
CandidRoot Solutions Private Limited
 
Download iTop VPN Free 6.1.0.5882 Crack Full Activated Pre Latest 2025
imang66g
 
Immersive experiences: what Pharo users do!
ESUG
 
Web Testing.pptx528278vshbuqffqhhqiwnwuq
studylike474
 
Summary Of Odoo 18.1 to 18.4 : The Way For Odoo 19
CandidRoot Solutions Private Limited
 
Visualising Data with Scatterplots in IBM SPSS Statistics.pptx
Version 1 Analytics
 
Using licensed Data Loss Prevention (DLP) as a strategic proactive data secur...
Q-Advise
 
classification of computer and basic part of digital computer
ravisinghrajpurohit3
 
Role Of Python In Programing Language.pptx
jaykoshti048
 
The-Dawn-of-AI-Reshaping-Our-World.pptxx
parthbhanushali307
 
10 posting ideas for community engagement with AI prompts
Pankaj Taneja
 
On Software Engineers' Productivity - Beyond Misleading Metrics
Romén Rodríguez-Gil
 
Protecting the Digital World Cyber Securit
dnthakkar16
 
New Download FL Studio Crack Full Version [Latest 2025]
imang66g
 
Contractor Management Platform and Software Solution for Compliance
SHEQ Network Limited
 
An Experience-Based Look at AI Lead Generation Pricing, Features & B2B Results
Thomas albart
 

Domain Driven Design using Laravel

  • 1. Domain Driven Design Using Laravel by Waqar Alamgir
  • 4. Lets Look at some Concepts 1. MVC Design Pattern 2. Entities 3. Active Records
  • 6. Entities “Many objects are found fundamentally by their attributes but rather by a thread of continuity and identity” – Eric Evans
  • 7. Person Waqar Alamgir Age 26 From Karachi Waqar Alamgir Age 26 From Karachi
  • 9. Person Waqar Alamgir Age 26 From Karachi Waqar Alamgir Age 26 From Karachi ID NAME AGE LOCATION 1 Waqar Alamgir 26 Karachi 2 Waqar Alamgir 26 Karachi
  • 10. Laravel Framewrok Laravel is a free, open source PHP web application framework, designed for the development of model–view– controller (MVC) web applications. Laravel is listed as the most popular PHP framework in 2013. Eloquent ORM (object-relational mapping) is an advanced PHP implementation of the active record pattern. Better Routing. Restful controllers provide an optional way for separating the logic behind serving HTTP GET and POST requests. Class auto loading. Migrations provide a version control system for database schemas.
  • 12. Philosophy In building large scale web applications MVC seems like a good solution in the initial design phase. However after having built a few large apps that have multiple entry points (web, cli, api etc) you start to find that MVC breaks down. Start using Domain Driven Design.
  • 13. A Common Application PRESENTATION LAYER Controllers Artisan Commands Queue Listeners SERVICE LAYER Sending Email Queuing up Jobs Repository Implementations COMMANDS / COMMAND BUS DOMAIN Entities Repository Interface
  • 14. What is Command Meat of the application Controller Artisan Command Queue Worker Whatever
  • 15. What is Command Meat of the application Commands i.e. Register Member Command
  • 16. What is Command Meat of the application Commands i.e. Register Member Command
  • 17. Advantages 1. No business policy in your controller 2. Your code shows intent 3. A single dedicated flow per user case 4. A single point of entry per user case 5. Easy to see which use cased are implemented
  • 18. Register Command class RegisterMemberCommand { public $displayName; public $email; public $password; public function __construct($displayName , $email , $password) { $this->displayName = $displayName; $this->email = $email; $this->password = $password; } }
  • 19. Register Command class RegisterMemberCommand { public $displayName; public $email; public $password; public function __construct($displayName , $email , $password) { $this->displayName = $displayName; $this->email = $email; $this->password = $password; } }
  • 20. The Final Destination Register Member Handler Register Member Command Meat of the application
  • 21. The Final Destination Register Member Handler Register Member Command Meat of the application Command Bus
  • 23. class ExecutionCommandBus implements CommandBus { private $container; private $mapper; public function __construct(Container $container , Mapper $mapper) { $this->container = $container; $this->mapper = $mapper; } public function execute($command) { $this->getHandler($command)->handle($command); } public function getHandler($command) { $class = $this->mapper- >getHandlerClassFor($command); return $this->container->make($class); } }
  • 24. How Does The Mapper Know?
  • 25. One Handle Per Command
  • 26. Let’s Look at very basic Register Member Command *with out any sequence*
  • 27. class RegisterMemberHandler implements Handler { private $memberRepository; public function __construct(MemberRepository $memberRepository) { $this->memberRepository = $memberRepository; } public function handle($command) { $member = Member::register( $command->displayName, $command->email, $command->password ); $this->memberRepository->save($member); } }
  • 28. class Member extends Eloquent { public static function register($displayName , $email , $password) { $member = new static([ ‘display_name’ => $displayName, ‘email’ => $email, ‘password’ => $password ]); return $member; } }
  • 30. Flow Review PRESENTATION LAYER Command SERVICE LAYER COMMAND BUS Command Handler DOMAIN Entities Repositories
  • 32. Simple Sequence Member Registers Subscribe to Mail Chimp Send Welcome Email Queue up 7 Day Email
  • 33. Domain Events Trigger Listeners Raise Event Typical PUB-SUB pattern Dispatch Event
  • 34. A Common Application PRESENTATION LAYER Controllers Artisan Commands Queue Listeners SERVICE LAYER Sending Email Queuing up Jobs Repository Implementations COMMANDS / COMMAND BUS Event Dispatcher DOMAIN Entities Repository Interface Domain Events
  • 35. Events/ Listener Breakdown Member Registers Subscribe to Mail Chimp Send Welcome Email Queue up 7 Day Email
  • 36. class MemberRegistered { public $member; public function __construct(Member $member) { $this->member = $member; } } class SendWelcomeEmail implements Listener { public function handle($event) { Mailer ::Queue(…); } }
  • 38. class EventGenerator { protected $pendingEvents = []; public function raise($event) { $this->pendingEvents = $event; } public function releaseEvents() { $events = $this->pendingEvents; $this->pendingEvents = [] ; return $events; } }
  • 39. class Member extends Eloquent { use EventGenerator ; public static function register($displayName , $email , $password) { $member = new static([ ‘display_name’ => $displayName, ‘email’ => $email, ‘password’ => $password ]); $member->raise(new MemberRegistered($member)) ; return $member; } }
  • 40. Interface Dispatcher { public function addListener($eventName , Listener $listener) ; public function dispatch($events) ; } // Register Listeners $dispatcher = new Dispatcher() ; $dispatcher-> addListener(‘MemberRegistered’ , new SubscribeToMailchimp) ; $dispatcher-> addListener(‘MemberRegistered’ , new SendWelcomeEmail) ; $dispatcher-> addListener(‘MemberRegistered’ , new SendOneWeekEmail) ;
  • 41. class RegisterMemberHandler implements Handler { private $memberRepository; private $dispatcher; public function __construct(MemberRepository $memberRepository , Dispatcher $dispatcher) { $this->memberRepository = $memberRepository; $this-> dispatcher = $dispatcher ; } public function handle($command) { $member = Member::register( $command->displayName, $command->email, $command->password ); $this->memberRepository->save($member); $this->dispatcher->dispatch($member-> releaseEvents()) ; } }
  • 42. More Information About DDD Domain-Driven Design: Tackling Complexity in the Heart of Software - Eric Evans Implementing Domain-Driven Design- Vaughn Vernon
  • 43. Thank You! Have more questions? Email: [email protected] Twitter: @wajrcs