Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Domain Driven
Design
Using Laravel
by
Waqar Alamgir
@folio_3 www.folio3.com Copyright 2015
Managing
Complexity
AKA Engineering
@folio_3 www.folio3.com Copyright 2015
Functional
Requirement
@folio_3 www.folio3.com Copyright 2015
Lets Look at some Concepts
1. MVC Design Pattern
2. Entities
3. Active Records
@folio_3 www.folio3.com Copyright 2015
MVC Design
Pattern
@folio_3 www.folio3.com Copyright 2015
Entities
“Many objects are found
fundamentally by their
attributes but rather by a
thread of continuity and
identity” – Er...
Person
Waqar Alamgir
Age 26
From Karachi
Waqar Alamgir
Age 26
From Karachi
@folio_3 www.folio3.com Copyright 2015
Active Records
@folio_3 www.folio3.com Copyright 2015
Person
Waqar Alamgir
Age 26
From Karachi
Waqar Alamgir
Age 26
From Karachi
ID NAME AGE LOCATION
1 Waqar Alamgir 26 Karachi...
Laravel is a free, open source PHP web application
framework, designed for the development of model–view–
controller (MVC)...
That’s not DDD
@folio_3 www.folio3.com Copyright 2015
Philosophy
In building large scale web applications MVC
seems like a good solution in the initial
design phase. However af...
A Common Application
PRESENTATION LAYER
Controllers
Artisan Commands
Queue Listeners
SERVICE LAYER
Sending Email
Queuing u...
What is Command
Meat of the application
Controller
Artisan Command
Queue Worker
Whatever
@folio_3 www.folio3.com Copyright...
What is Command
Meat of the application
Commands
i.e. Register Member
Command
@folio_3 www.folio3.com Copyright 2015
What is Command
Meat of the application
Commands
i.e. Register Member
Command
@folio_3 www.folio3.com Copyright 2015
Advantages
1. No business policy in your controller
2. Your code shows intent
3. A single dedicated flow per use case
4. A...
Register Command
class RegisterMemberCommand
{
public $displayName;
public $email;
public $password;
public function __con...
Register Command
class RegisterMemberCommand
{
public $displayName;
public $email;
public $password;
public function __con...
The Final Destination
Register Member
Handler
Register Member
Command
Meat of the application
@folio_3 www.folio3.com Copy...
The Final Destination
Register Member
Handler
Register Member
Command
Meat of the application
Command Bus
@folio_3 www.fol...
Implementing
Command Bus
@folio_3 www.folio3.com Copyright 2015
class ExecutionCommandBus implements CommandBus
{
private $container;
private $mapper;
public function __construct(Contain...
How Does The
Mapper Know?
@folio_3 www.folio3.com Copyright 2015
One Handle Per
Command
@folio_3 www.folio3.com Copyright 2015
Let’s Look at
very basic
Register Member
Command
*without any sequence*
@folio_3 www.folio3.com Copyright 2015
class RegisterMemberHandler implements Handler
{
private $memberRepository;
public function __construct(MemberRepository
$...
class Member extends Eloquent
{
public static function register($displayName , $email ,
$password)
{
$member = new static(...
Flow Review
@folio_3 www.folio3.com Copyright 2015
Flow Review
PRESENTATION
LAYER
Command
SERVICE
LAYER
COMMAND BUS Command Handler
DOMAIN
Entities
Repositories
@folio_3 www...
Simple Sequence
@folio_3 www.folio3.com Copyright 2015
Simple Sequence
Member Registers
Subscribe to Mail
Chimp
Send Welcome Email
Queue up 7 Day Email
@folio_3 www.folio3.com C...
Domain Events
Trigger
Listeners
Raise Event
Typical PUB-SUB pattern
Dispatch Event
@folio_3 www.folio3.com Copyright 2015
A Common Application
PRESENTATION LAYER
Controllers
Artisan Commands
Queue Listeners
SERVICE LAYER
Sending Email
Queuing u...
Events/ Listener
Breakdown
Member
Registers
Subscribe to Mail
Chimp
Send Welcome Email
Queue up 7 Day
Email
@folio_3 www.f...
class MemberRegistered
{
public $member;
public function __construct(Member $member)
{
$this->member = $member;
}
}
class ...
Throwing Domain
Events
@folio_3 www.folio3.com Copyright 2015
class EventGenerator
{
protected $pendingEvents = [];
public function raise($event)
{
$this->pendingEvents = $event;
}
pub...
class Member extends Eloquent
{
use EventGenerator ;
public static function register($displayName , $email ,
$password)
{
...
Interface Dispatcher
{
public function addListener($eventName , Listener
$listener) ;
public function dispatch($events) ;
...
class RegisterMemberHandler implements Handler
{
private $memberRepository;
private $dispatcher;
public function __constru...
More Information
About DDD
Domain-Driven Design: Tackling
Complexity in the Heart of
Software - Eric Evans
Implementing Do...
Upcoming SlideShare
Loading in …5
×

Domain Driven Design

1,307 views

Published on

Lets Look at some Concepts
1. MVC Design Pattern
2. Entities
3. Active Records

Published in: Design
  • Login to see the comments

Domain Driven Design

  1. 1. Domain Driven Design Using Laravel by Waqar Alamgir @folio_3 www.folio3.com Copyright 2015
  2. 2. Managing Complexity AKA Engineering @folio_3 www.folio3.com Copyright 2015
  3. 3. Functional Requirement @folio_3 www.folio3.com Copyright 2015
  4. 4. Lets Look at some Concepts 1. MVC Design Pattern 2. Entities 3. Active Records @folio_3 www.folio3.com Copyright 2015
  5. 5. MVC Design Pattern @folio_3 www.folio3.com Copyright 2015
  6. 6. Entities “Many objects are found fundamentally by their attributes but rather by a thread of continuity and identity” – Eric Evans @folio_3 www.folio3.com Copyright 2015
  7. 7. Person Waqar Alamgir Age 26 From Karachi Waqar Alamgir Age 26 From Karachi @folio_3 www.folio3.com Copyright 2015
  8. 8. Active Records @folio_3 www.folio3.com Copyright 2015
  9. 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 @folio_3 www.folio3.com Copyright 2015
  10. 10. 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. Laravel Framewrok @folio_3 Copyright 2015www.folio3.com
  11. 11. That’s not DDD @folio_3 www.folio3.com Copyright 2015
  12. 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. @folio_3 www.folio3.com Copyright 2015
  13. 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 @folio_3 www.folio3.com Copyright 2015
  14. 14. What is Command Meat of the application Controller Artisan Command Queue Worker Whatever @folio_3 www.folio3.com Copyright 2015
  15. 15. What is Command Meat of the application Commands i.e. Register Member Command @folio_3 www.folio3.com Copyright 2015
  16. 16. What is Command Meat of the application Commands i.e. Register Member Command @folio_3 www.folio3.com Copyright 2015
  17. 17. Advantages 1. No business policy in your controller 2. Your code shows intent 3. A single dedicated flow per use case 4. A single point of entry per use case 5. Easy to see which use cases are implemented @folio_3 www.folio3.com Copyright 2015
  18. 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; } } @folio_3 www.folio3.com Copyright 2015
  19. 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; } } @folio_3 www.folio3.com Copyright 2015
  20. 20. The Final Destination Register Member Handler Register Member Command Meat of the application @folio_3 www.folio3.com Copyright 2015
  21. 21. The Final Destination Register Member Handler Register Member Command Meat of the application Command Bus @folio_3 www.folio3.com Copyright 2015
  22. 22. Implementing Command Bus @folio_3 www.folio3.com Copyright 2015
  23. 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); }} @folio_3 www.folio3.com Copyright 2015
  24. 24. How Does The Mapper Know? @folio_3 www.folio3.com Copyright 2015
  25. 25. One Handle Per Command @folio_3 www.folio3.com Copyright 2015
  26. 26. Let’s Look at very basic Register Member Command *without any sequence* @folio_3 www.folio3.com Copyright 2015
  27. 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); } } @folio_3 www.folio3.com Copyright 2015
  28. 28. class Member extends Eloquent { public static function register($displayName , $email , $password) { $member = new static([ ‘display_name’ => $displayName, ‘email’ => $email, ‘password’ => $password ]); return $member; } } @folio_3 www.folio3.com Copyright 2015
  29. 29. Flow Review @folio_3 www.folio3.com Copyright 2015
  30. 30. Flow Review PRESENTATION LAYER Command SERVICE LAYER COMMAND BUS Command Handler DOMAIN Entities Repositories @folio_3 www.folio3.com Copyright 2015
  31. 31. Simple Sequence @folio_3 www.folio3.com Copyright 2015
  32. 32. Simple Sequence Member Registers Subscribe to Mail Chimp Send Welcome Email Queue up 7 Day Email @folio_3 www.folio3.com Copyright 2015
  33. 33. Domain Events Trigger Listeners Raise Event Typical PUB-SUB pattern Dispatch Event @folio_3 www.folio3.com Copyright 2015
  34. 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 @folio_3 www.folio3.com Copyright 2015
  35. 35. Events/ Listener Breakdown Member Registers Subscribe to Mail Chimp Send Welcome Email Queue up 7 Day Email @folio_3 www.folio3.com Copyright 2015
  36. 36. class MemberRegistered { public $member; public function __construct(Member $member) { $this->member = $member; } } class SendWelcomeEmail implements Listener { public function handle($event) { Mailer ::Queue(…); } } @folio_3 www.folio3.com Copyright 2015
  37. 37. Throwing Domain Events @folio_3 www.folio3.com Copyright 2015
  38. 38. class EventGenerator { protected $pendingEvents = []; public function raise($event) { $this->pendingEvents = $event; } public function releaseEvents() { $events = $this->pendingEvents; $this->pendingEvents = [] ; return $events; } } @folio_3 www.folio3.com Copyright 2015
  39. 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; } } @folio_3 www.folio3.com Copyright 2015
  40. 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) ; @folio_3 www.folio3.com Copyright 2015
  41. 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()) ; } } @folio_3 www.folio3.com Copyright 2015
  42. 42. More Information About DDD Domain-Driven Design: Tackling Complexity in the Heart of Software - Eric Evans Implementing Domain-Driven Design- Vaughn Vernon @folio_3 www.folio3.com Copyright 2015

×