Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
HI, I’M SHAWN
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
LARAVEL.IO ORIGIN
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
Laravel.IO Now
LARAVEL.IO FORUM
from Nick Spelt an...
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
AKA ENGINEERING
MANAGING COMPLEXITY
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
FUNCTIONAL REQUIREMENTS
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
USE CASES
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
ENTITIES
Many objects are not fundamentally define...
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
PeoplePERSON
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
Jane Doe
People
Jane Doe
PERSON
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
Jane Doe
People
Jane DoeJane Doe
PERSON
Jane Doe
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
Jane Doe
PERSON
Age: 27
Jane Doe
Age: 27
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
Jane Doe
PERSON
Age: 27
From: NYC
Jane Doe
Age: 27...
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
THE ACTIVERECORD PATTERN
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
ID: 1 ID: 2
Jane Doe
PERSON
Age: 27
From: NYC
Jane...
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
ENTITIES AND ACTIVERECORD
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
THIS IS NOT DDD
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
LAYERED ARCHITECTURE
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
A COMMON APPLICATION
PRESENTATION LAYER
Controller...
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
PRESENTATION LAYER
Controllers
Artisan Commands
Qu...
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
PRESENTATION LAYER
Controllers
Artisan Commands
Qu...
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
PRESENTATION LAYER
Controllers
Artisan Commands
Qu...
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
A COMMAND ORIENTED INTERFACE
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
MEAT OF THE APPLICATION
WHAT IS A COMMAND
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
Controller
Artisan Command
Queue Worker
Whatever
M...
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
WHAT IS A COMMAND
MEAT OF THE APPLICATION
REGISTER...
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
WHAT IS A COMMAND
MEAT OF THE APPLICATION
REGISTER...
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
WHAT IS A COMMAND
REGISTER MEMBER
COMMAND
MEAT OF ...
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
Some Advantages
- No business policy in your contr...
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
COMMAND ANATOMY
class RegisterMemberCommand
{
public $displayName;
public $email;
public $password;
public function __construct($displayNa...
class RegisterMemberCommand
{
public $displayName;
public $email;
public $password;
public function __construct($displayNa...
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
WHAT IS HAPPENING INSIDE?
MEAT OF THE APPLICATION
...
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
THE FINAL DESTINATION
MEAT OF THE APPLICATION
REGI...
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
THE FINAL DESTINATION
MEAT OF THE APPLICATION
?REG...
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
THE TRANSPORT MECHANISM
MEAT OF THE APPLICATION
CO...
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
COMMAND BUS IMPLEMENTATION
class ExecutionCommandBus implements CommandBus
{
private $container;
private $mapper;
public function __construct(Contain...
class ExecutionCommandBus implements CommandBus
{
private $container;
private $mapper;
public function __construct(Contain...
class ExecutionCommandBus implements CommandBus
{
private $container;
private $mapper;
public function __construct(Contain...
class ExecutionCommandBus implements CommandBus
{
private $container;
private $mapper;
public function __construct(Contain...
class ExecutionCommandBus implements CommandBus
{
private $container;
private $mapper;
public function __construct(Contain...
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
HOW DOES THE MAPPER KNOW?
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
ONE HANDLER PER COMMAND
class RegisterMemberHandler implements Handler
{
private $memberRepository;
public function __construct(MemberRepository $...
class RegisterMemberHandler implements Handler
{
private $memberRepository;
public function __construct(MemberRepository $...
class RegisterMemberHandler implements Handler
{
private $memberRepository;
public function __construct(MemberRepository $...
class RegisterMemberHandler implements Handler
{
private $memberRepository;
public function __construct(MemberRepository $...
class Member extends Eloquent
{
public static function register($displayName, $email, $password)
{
$member = new static([
...
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
DOMAIN IMPLICATION
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
FLOW REVIEW
PRESENTATION
LAYER
SERVICE LAYER DOMAIN
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
FLOW REVIEW
PRESENTATION
LAYER
SERVICE LAYER DOMAI...
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
FLOW REVIEW
PRESENTATION
LAYER
SERVICE LAYER DOMAI...
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
FLOW REVIEW
PRESENTATION
LAYER
SERVICE LAYER DOMAI...
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
FLOW REVIEW
PRESENTATION
LAYER
SERVICE LAYER DOMAI...
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
HANDLING COMPLEX SEQUENCES
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
MEMBER REGISTERS
SEND WELCOME EMAIL
SUBSCRIBE TO M...
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
MEMBER REPLIES TO THREAD
NOTIFY THREAD SUBSCRIBERS...
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
MEMBER REPLIES TO THREAD
NOTIFY THREAD SUBSCRIBERS...
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
DOMAIN EVENTS
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
TYPICAL PUB-SUB PATTERN
DISPATCH EVENTRAISE EVENT ...
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
PRESENTATION LAYER
Controllers
Artisan Commands
Qu...
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
PRESENTATION LAYER
Controllers
Artisan Commands
Qu...
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
MEMBER REGISTERS
SEND WELCOME EMAIL
SUBSCRIBE TO M...
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
MEMBER REGISTERS
SEND WELCOME EMAIL
SUBSCRIBE TO M...
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
MemberRegistered
SEND WELCOME EMAIL
SUBSCRIBE TO M...
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
MemberRegistered
SEND WELCOME EMAIL
SUBSCRIBE TO M...
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
MemberRegistered
SendWelcomeMail
SubscribeToMailch...
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
MemberRegistered SendWelcomeMail
SendOneWeekEmail
...
class MemberRegistered
{
public $member;
public function __construct(Member $member)
{
$this->member = $member;
}
}
class ...
class MemberRegistered
{
public $member;
public function __construct(Member $member)
{
$this->member = $member;
}
}
class ...
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
THROWING DOMAIN EVENTS
trait EventGenerator
{
protected $pendingEvents = [];
protected function raise($event)
{
$this->pendingEvents[] = $event;
...
trait EventGenerator
{
protected $pendingEvents = [];
protected function raise($event)
{
$this->pendingEvents[] = $event;
...
trait EventGenerator
{
protected $pendingEvents = [];
protected function raise($event)
{
$this->pendingEvents[] = $event;
...
trait EventGenerator
{
protected $pendingEvents = [];
protected function raise($event)
{
$this->pendingEvents[] = $event;
...
class Member extends Eloquent
{
use EventGenerator;
public static function register($displayName, $email, $password)
{
$me...
class Member extends Eloquent
{
use EventGenerator;
public static function register($displayName, $email, $password)
{
$me...
class Member extends Eloquent
{
use EventGenerator;
public static function register($displayName, $email, $password)
{
$me...
class Member extends Eloquent
{
use EventGenerator;
public static function register($displayName, $email, $password)
{
$me...
class Member extends Eloquent
{
use EventGenerator;
public static function register($displayName, $email, $password)
{
$me...
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
EVENT DISPATCHING
interface Dispatcher
{
public function addListener($eventName, Listener $listener);
public function dispatch($events);
}
/...
interface Dispatcher
{
public function addListener($eventName, Listener $listener);
public function dispatch($events);
}
/...
interface Dispatcher
{
public function addListener($eventName, Listener $listener);
public function dispatch($events);
}
/...
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
THE FULL COMMAND HANDLER
Heads Up...
class RegisterMemberHandler implements Handler
{
private $memberRepository;
private $dispatcher;
public function __constru...
class RegisterMemberHandler implements Handler
{
private $memberRepository;
private $dispatcher;
public function __constru...
class RegisterMemberHandler implements Handler
{
private $memberRepository;
private $dispatcher;
public function __constru...
class RegisterMemberHandler implements Handler
{
private $memberRepository;
private $dispatcher;
public function __constru...
class RegisterMemberHandler implements Handler
{
private $memberRepository;
private $dispatcher;
public function __constru...
class RegisterMemberHandler implements Handler
{
private $memberRepository;
private $dispatcher;
public function __constru...
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
MEMBER REPLIES TO THREAD
NOTIFY THREAD SUBSCRIBERS...
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
MEMBER REPLIES TO THREAD
NOTIFY THREAD SUBSCRIBERS...
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
MEMBER REPLIES TO THREAD
NOTIFY THREAD SUBSCRIBERS...
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
MemberRepliedToThread
NOTIFY THREAD SUBSCRIBERS
w
...
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
MemberRepliedToThread
NOTIFY THREAD SUBSCRIBERS
NO...
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
MemberRepliedToThread
NotifyThreadSubscribers
Noti...
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
MEMBER IS NOTIFIED
COMPLEX SEQUENCE
SEND NOTIFICAT...
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
MEMBER IS NOTIFIED
COMPLEX SEQUENCE
SEND NOTIFICAT...
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
MemberNotificationSent
COMPLEX SEQUENCE
SEND NOTIF...
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
MemberNotificationSent
COMPLEX SEQUENCE
SEND NOTIF...
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
MemberNotificationSent
COMPLEX SEQUENCE
SendNotifi...
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
DOMAIN EVENTS
MemberRepliedToThread NotifyThreadSu...
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
Some Disadvantages
- Can be harder to understand w...
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
DOMAIN-DRIVEN DESIGN
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
MORE INFORMATION ABOUT DDD
http://verraes.net
http...
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
Even More Information
A very quick read + it’s fre...
Tickets are available at http://Laracon.EU
Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC
Thank you Laracon 2014!
Hopefully, I talked so rid...
Laravel.IO A Use-Case Architecture
Upcoming SlideShare
Loading in...5
×

Laravel.IO A Use-Case Architecture

7,641

Published on

A simple architecture is perfect for a simple application. But, as the application grows in its complexity, the architecture must become more complex in order to prevent it from becoming unmaintainable.

In this talk we discuss some ideas for simplifying complex code bases.

We also discuss the important distinctions between presentation, service, and domain layers and strategies for separating high-level business policy from implementation.

Some Domain-Driven Design topics are discussed, but this is not a talk about DDD. DDD is not about design patterns, but rather is about business analysis, communication, and much more.

2 Comments
35 Likes
Statistics
Notes
No Downloads
Views
Total Views
7,641
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
208
Comments
2
Likes
35
Embeds 0
No embeds

No notes for slide

Transcript of "Laravel.IO A Use-Case Architecture"

  1. 1. LARAVEL.IO A USE CASE ARCHITECTURE
  2. 2. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC HI, I’M SHAWN
  3. 3. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC LARAVEL.IO ORIGIN
  4. 4. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC Laravel.IO Now LARAVEL.IO FORUM from Nick Spelt and myself LIONA (LioBot) from Sam Evaskitas and Matthew Machuga LARAVEL WEEKLY NEWSLETTER by Dries Vints PODCAST http://bit.ly/laravelio-podcast Assets available for contribution at: https://github.com/LaravelIO
  5. 5. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC AKA ENGINEERING MANAGING COMPLEXITY
  6. 6. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC FUNCTIONAL REQUIREMENTS
  7. 7. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC USE CASES
  8. 8. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC ENTITIES Many objects are not fundamentally defined by their attributes, but rather by a thread of continuity and identity. - Eric Evans “
  9. 9. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC PeoplePERSON
  10. 10. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC Jane Doe People Jane Doe PERSON
  11. 11. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC Jane Doe People Jane DoeJane Doe PERSON Jane Doe
  12. 12. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC Jane Doe PERSON Age: 27 Jane Doe Age: 27
  13. 13. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC Jane Doe PERSON Age: 27 From: NYC Jane Doe Age: 27 From: NYC
  14. 14. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC THE ACTIVERECORD PATTERN
  15. 15. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC ID: 1 ID: 2 Jane Doe PERSON Age: 27 From: NYC Jane Doe Age: 27 From: NYC People Table ID 1 2 Age 27 27 From NYC NYC Name Jane Doe Jane Doe
  16. 16. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC ENTITIES AND ACTIVERECORD
  17. 17. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC THIS IS NOT DDD
  18. 18. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC LAYERED ARCHITECTURE
  19. 19. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC A COMMON APPLICATION PRESENTATION LAYER Controllers Artisan Commands Queue Listeners
  20. 20. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC PRESENTATION LAYER Controllers Artisan Commands Queue Listeners DOMAIN Entities Repository Interfaces A COMMON APPLICATION
  21. 21. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC PRESENTATION LAYER Controllers Artisan Commands Queue Listeners SERVICE LAYER Sending Email Queueing up Jobs Repository Implementations DOMAIN Entities Repository Interfaces A COMMON APPLICATION
  22. 22. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC PRESENTATION LAYER Controllers Artisan Commands Queue Listeners SERVICE LAYER Sending Email Queueing up Jobs Repository Implementations Commands / Command Bus DOMAIN Entities Repository Interfaces A COMMON APPLICATION
  23. 23. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC A COMMAND ORIENTED INTERFACE
  24. 24. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC MEAT OF THE APPLICATION WHAT IS A COMMAND
  25. 25. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC Controller Artisan Command Queue Worker Whatever MEAT OF THE APPLICATION WHAT IS A COMMAND
  26. 26. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC WHAT IS A COMMAND MEAT OF THE APPLICATION REGISTER MEMBER COMMAND
  27. 27. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC WHAT IS A COMMAND MEAT OF THE APPLICATION REGISTER MEMBER COMMAND
  28. 28. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC WHAT IS A COMMAND REGISTER MEMBER COMMAND MEAT OF THE APPLICATION
  29. 29. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC Some Advantages - No business policy in your controllers - Your code shows intent - A single dedicated flow per use case - A single point of entry per use case - Easy to see which use cases are implemented
  30. 30. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC COMMAND ANATOMY
  31. 31. class RegisterMemberCommand { public $displayName; public $email; public $password; public function __construct($displayName, $email, $password) { $this->displayName = $displayName; $this->email = $email; $this->password = $password; } }
  32. 32. class RegisterMemberCommand { public $displayName; public $email; public $password; public function __construct($displayName, $email, $password) { $this->displayName = $displayName; $this->email = $email; $this->password = $password; } }
  33. 33. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC WHAT IS HAPPENING INSIDE? MEAT OF THE APPLICATION REGISTER MEMBER COMMAND
  34. 34. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC THE FINAL DESTINATION MEAT OF THE APPLICATION REGISTER MEMBER HANDLER REGISTER MEMBER COMMAND
  35. 35. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC THE FINAL DESTINATION MEAT OF THE APPLICATION ?REGISTER MEMBER COMMAND REGISTER MEMBER HANDLER
  36. 36. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC THE TRANSPORT MECHANISM MEAT OF THE APPLICATION COMMAND BUSREGISTER MEMBER COMMAND REGISTER MEMBER HANDLER
  37. 37. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC COMMAND BUS IMPLEMENTATION
  38. 38. 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); } private function getHandler($command) { $class = $this->mapper->getHandlerClassFor($command); return $this->container->make($class); } }
  39. 39. 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); } private function getHandler($command) { $class = $this->mapper->getHandlerClassFor($command); return $this->container->make($class); } }
  40. 40. 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); } private function getHandler($command) { $class = $this->mapper->getHandlerClassFor($command); return $this->container->make($class); } }
  41. 41. 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); } private function getHandler($command) { $class = $this->mapper->getHandlerClassFor($command); return $this->container->make($class); } }
  42. 42. 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); } private function getHandler($command) { $class = $this->mapper->getHandlerClassFor($command); return $this->container->make($class); } }
  43. 43. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC HOW DOES THE MAPPER KNOW?
  44. 44. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC ONE HANDLER PER COMMAND
  45. 45. 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); } }
  46. 46. 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); } }
  47. 47. 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); } }
  48. 48. 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); } }
  49. 49. class Member extends Eloquent { public static function register($displayName, $email, $password) { $member = new static([ 'display_name' => $displayName, 'email' => $email, 'password' => $password, ]); return $member; } }
  50. 50. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC DOMAIN IMPLICATION
  51. 51. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC FLOW REVIEW PRESENTATION LAYER SERVICE LAYER DOMAIN
  52. 52. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC FLOW REVIEW PRESENTATION LAYER SERVICE LAYER DOMAIN COMMAND
  53. 53. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC FLOW REVIEW PRESENTATION LAYER SERVICE LAYER DOMAIN COMMAND COMMAND BUS
  54. 54. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC FLOW REVIEW PRESENTATION LAYER SERVICE LAYER DOMAIN COMMAND COMMAND BUS COMMAND HANDLER
  55. 55. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC FLOW REVIEW PRESENTATION LAYER SERVICE LAYER DOMAIN COMMAND COMMAND BUS COMMAND HANDLER ENTITIES REPOSITORIES
  56. 56. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC HANDLING COMPLEX SEQUENCES
  57. 57. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC MEMBER REGISTERS SEND WELCOME EMAIL SUBSCRIBE TO MAILCHIMP QUEUE UP 7 DAY EMAIL SIMPLE SEQUENCE
  58. 58. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC MEMBER REPLIES TO THREAD NOTIFY THREAD SUBSCRIBERS w NOTIFY TAGGED USERS COMPLEX SEQUENCE
  59. 59. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC MEMBER REPLIES TO THREAD NOTIFY THREAD SUBSCRIBERS w NOTIFY TAGGED USERS COMPLEX SEQUENCE SEND NOTIFICATION EMAIL ADD NOTIFICATION DIGEST QUEUE ENTRY SEND NO NOTIFICATION
  60. 60. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC DOMAIN EVENTS
  61. 61. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC TYPICAL PUB-SUB PATTERN DISPATCH EVENTRAISE EVENT TRIGGER LISTENERS
  62. 62. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC PRESENTATION LAYER Controllers Artisan Commands Queue Listeners SERVICE LAYER Sending Email Queueing up Jobs Repository Implementations Commands / Command Bus DOMAIN Entities Repository Interfaces A COMMON APPLICATION
  63. 63. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC PRESENTATION LAYER Controllers Artisan Commands Queue Listeners SERVICE LAYER Sending Email Queueing up Jobs Repository Implementations Commands / Command Bus Event Dispatcher DOMAIN Entities Repository Interfaces Domain Events A COMMON APPLICATION
  64. 64. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC MEMBER REGISTERS SEND WELCOME EMAIL SUBSCRIBE TO MAILCHIMP QUEUE UP 7 DAY EMAIL DOMAIN EVENTS
  65. 65. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC MEMBER REGISTERS SEND WELCOME EMAIL SUBSCRIBE TO MAILCHIMP QUEUE UP 7 DAY EMAIL EVENT / LISTENER BREAKDOWN
  66. 66. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC MemberRegistered SEND WELCOME EMAIL SUBSCRIBE TO MAILCHIMP QUEUE UP 7 DAY EMAIL EVENT / LISTENER BREAKDOWN
  67. 67. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC MemberRegistered SEND WELCOME EMAIL SUBSCRIBE TO MAILCHIMP QUEUE UP 7 DAY EMAIL EVENT / LISTENER BREAKDOWN
  68. 68. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC MemberRegistered SendWelcomeMail SubscribeToMailchimp SendOneWeekEmail EVENT / LISTENER BREAKDOWN
  69. 69. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC MemberRegistered SendWelcomeMail SendOneWeekEmail SubscribeToMailchimp EVENTS LISTENERS EVENT / LISTENER BREAKDOWN
  70. 70. class MemberRegistered { public $member; public function __construct(Member $member) { $this->member = $member; } } class SendWelcomeEmail implements Listener { public function handle($event) { Mailer::queue(...); } }
  71. 71. class MemberRegistered { public $member; public function __construct(Member $member) { $this->member = $member; } } class SendWelcomeEmail implements Listener { public function handle($event) { Mailer::queue(...); } }
  72. 72. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC THROWING DOMAIN EVENTS
  73. 73. trait EventGenerator { protected $pendingEvents = []; protected function raise($event) { $this->pendingEvents[] = $event; } public function releaseEvents() { $events = $this->pendingEvents; $this->pendingEvents = []; return $events; } }
  74. 74. trait EventGenerator { protected $pendingEvents = []; protected function raise($event) { $this->pendingEvents[] = $event; } public function releaseEvents() { $events = $this->pendingEvents; $this->pendingEvents = []; return $events; } }
  75. 75. trait EventGenerator { protected $pendingEvents = []; protected function raise($event) { $this->pendingEvents[] = $event; } public function releaseEvents() { $events = $this->pendingEvents; $this->pendingEvents = []; return $events; } }
  76. 76. trait EventGenerator { protected $pendingEvents = []; protected function raise($event) { $this->pendingEvents[] = $event; } public function releaseEvents() { $events = $this->pendingEvents; $this->pendingEvents = []; return $events; } }
  77. 77. 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 MemberJoined($member)); return $member; } }
  78. 78. 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; } }
  79. 79. 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; } }
  80. 80. 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; } }
  81. 81. 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; } }
  82. 82. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC EVENT DISPATCHING
  83. 83. interface Dispatcher { public function addListener($eventName, Listener $listener); public function dispatch($events); } // Register Listeners $dispatcher = new Dispatcher; $dispatcher->addListener('MemberRegistered', new SendWelcomeEmail); $dispatcher->addListener('MemberRegistered', new SubscribeToMailchimp); $dispatcher->addListener('MemberRegistered', new SendOneWeekEmail); // Dispatch Events $dispatcher->dispatch($events);
  84. 84. interface Dispatcher { public function addListener($eventName, Listener $listener); public function dispatch($events); } // Register Listeners $dispatcher = new Dispatcher; $dispatcher->addListener('MemberRegistered', new SendWelcomeEmail); $dispatcher->addListener('MemberRegistered’, new SubscribeToMailchimp); $dispatcher->addListener('MemberRegistered', new SendOneWeekEmail); // Dispatch Events $dispatcher->dispatch($events);
  85. 85. interface Dispatcher { public function addListener($eventName, Listener $listener); public function dispatch($events); } // Register Listeners $dispatcher = new Dispatcher; $dispatcher->addListener('MemberRegistered', new SendWelcomeEmail); $dispatcher->addListener('MemberRegistered’, new SubscribeToMailchimp); $dispatcher->addListener('MemberRegistered', new SendOneWeekEmail); // Dispatch Events $dispatcher->dispatch($events);
  86. 86. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC THE FULL COMMAND HANDLER Heads Up...
  87. 87. 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()); } }
  88. 88. 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()); } }
  89. 89. 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()); } }
  90. 90. 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()); } }
  91. 91. 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()); } }
  92. 92. 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()); } }
  93. 93. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC MEMBER REPLIES TO THREAD NOTIFY THREAD SUBSCRIBERS w NOTIFY TAGGED USERS COMPLEX SEQUENCE SEND NOTIFICATION EMAIL ADD NOTIFICATION DIGEST QUEUE ENTRY SEND NO NOTIFICATION
  94. 94. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC MEMBER REPLIES TO THREAD NOTIFY THREAD SUBSCRIBERS w NOTIFY TAGGED USERS COMPLEX SEQUENCE
  95. 95. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC MEMBER REPLIES TO THREAD NOTIFY THREAD SUBSCRIBERS w NOTIFY TAGGED USERS COMPLEX SEQUENCE
  96. 96. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC MemberRepliedToThread NOTIFY THREAD SUBSCRIBERS w NOTIFY TAGGED USERS COMPLEX SEQUENCE
  97. 97. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC MemberRepliedToThread NOTIFY THREAD SUBSCRIBERS NOTIFY TAGGED USERS COMPLEX SEQUENCE
  98. 98. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC MemberRepliedToThread NotifyThreadSubscribers NotifyTaggedUsers COMPLEX SEQUENCE
  99. 99. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC MEMBER IS NOTIFIED COMPLEX SEQUENCE SEND NOTIFICATION EMAIL
  100. 100. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC MEMBER IS NOTIFIED COMPLEX SEQUENCE SEND NOTIFICATION EMAIL
  101. 101. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC MemberNotificationSent COMPLEX SEQUENCE SEND NOTIFICATION EMAIL
  102. 102. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC MemberNotificationSent COMPLEX SEQUENCE SEND NOTIFICATION EMAIL
  103. 103. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC MemberNotificationSent COMPLEX SEQUENCE SendNotificationEmail
  104. 104. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC DOMAIN EVENTS MemberRepliedToThread NotifyThreadSubscribers SendNotificationEmail NotifyTaggedMembers EVENTS LISTENERS MemberNotificationSent
  105. 105. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC Some Disadvantages - Can be harder to understand what’s happening - Requires more infrastructure - Events can be hard to debug
  106. 106. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC DOMAIN-DRIVEN DESIGN
  107. 107. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC MORE INFORMATION ABOUT DDD http://verraes.net http://rosstuck.com http://dddinphp.org Domain-Driven Design by Eric Evans Implementing Domain-Driven Design by Vaughn Vernon
  108. 108. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC Even More Information A very quick read + it’s free http://www.infoq.com/minibooks/domain-driven-design-quickly Martin Fowler http://martinfowler.com/bliki/CommandOrientedInterface.html http://martinfowler.com/eaaDev/DomainEvent.html
  109. 109. Tickets are available at http://Laracon.EU
  110. 110. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC Thank you Laracon 2014! Hopefully, I talked so ridiculously fast that there’s time for questions. Twitter @ShawnMcCool Special Thanks to Nick Spelt and Mitchell van Wijngaarden

×