Your SlideShare is downloading. ×
  • Like
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Now you can save presentations on your phone or tablet

Available for both IPhone and Android

Text the download link to your phone

Standard text messaging rates apply

Laravel.IO A Use-Case Architecture

  • 5,121 views
Published

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 …

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.

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
  • @Bradley the presentation has been added here. https://www.youtube.com/watch?v=2_380DKU93U
    Are you sure you want to
    Your message goes here
  • This looks awesome, I use service bus in MarionetteJS and I love it, is there a link to the presentation?
    Are you sure you want to
    Your message goes here
No Downloads

Views

Total Views
5,121
On SlideShare
0
From Embeds
0
Number of Embeds
2

Actions

Shares
Downloads
118
Comments
2
Likes
21

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. LARAVEL.IO A USE CASE ARCHITECTURE
  • 2. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC HI, I’M SHAWN
  • 3. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC LARAVEL.IO ORIGIN
  • 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. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC AKA ENGINEERING MANAGING COMPLEXITY
  • 6. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC FUNCTIONAL REQUIREMENTS
  • 7. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC USE CASES
  • 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. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC PeoplePERSON
  • 10. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC Jane Doe People Jane Doe PERSON
  • 11. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC Jane Doe People Jane DoeJane Doe PERSON Jane Doe
  • 12. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC Jane Doe PERSON Age: 27 Jane Doe Age: 27
  • 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. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC THE ACTIVERECORD PATTERN
  • 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. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC ENTITIES AND ACTIVERECORD
  • 17. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC THIS IS NOT DDD
  • 18. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC LAYERED ARCHITECTURE
  • 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. 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. 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. 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. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC A COMMAND ORIENTED INTERFACE
  • 24. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC MEAT OF THE APPLICATION WHAT IS A COMMAND
  • 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. 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. 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. 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. 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. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC COMMAND ANATOMY
  • 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. class RegisterMemberCommand { public $displayName; public $email; public $password; public function __construct($displayName, $email, $password) { $this->displayName = $displayName; $this->email = $email; $this->password = $password; } }
  • 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. 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. 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. 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. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC COMMAND BUS IMPLEMENTATION
  • 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. 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. 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. 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. 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. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC HOW DOES THE MAPPER KNOW?
  • 44. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC ONE HANDLER PER COMMAND
  • 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. 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. 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. 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. class Member extends Eloquent { public static function register($displayName, $email, $password) { $member = new static([ 'display_name' => $displayName, 'email' => $email, 'password' => $password, ]); return $member; } }
  • 50. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC DOMAIN IMPLICATION
  • 51. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC FLOW REVIEW PRESENTATION LAYER SERVICE LAYER DOMAIN
  • 52. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC FLOW REVIEW PRESENTATION LAYER SERVICE LAYER DOMAIN COMMAND
  • 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. 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. 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. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC HANDLING COMPLEX SEQUENCES
  • 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. 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. 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. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC DOMAIN EVENTS
  • 61. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC TYPICAL PUB-SUB PATTERN DISPATCH EVENTRAISE EVENT TRIGGER LISTENERS
  • 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. 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. 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. 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. 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. 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. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC MemberRegistered SendWelcomeMail SubscribeToMailchimp SendOneWeekEmail EVENT / LISTENER BREAKDOWN
  • 69. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC MemberRegistered SendWelcomeMail SendOneWeekEmail SubscribeToMailchimp EVENTS LISTENERS EVENT / LISTENER BREAKDOWN
  • 70. class MemberRegistered { public $member; public function __construct(Member $member) { $this->member = $member; } } class SendWelcomeEmail implements Listener { public function handle($event) { Mailer::queue(...); } }
  • 71. class MemberRegistered { public $member; public function __construct(Member $member) { $this->member = $member; } } class SendWelcomeEmail implements Listener { public function handle($event) { Mailer::queue(...); } }
  • 72. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC THROWING DOMAIN EVENTS
  • 73. trait EventGenerator { protected $pendingEvents = []; protected function raise($event) { $this->pendingEvents[] = $event; } public function releaseEvents() { $events = $this->pendingEvents; $this->pendingEvents = []; return $events; } }
  • 74. trait EventGenerator { protected $pendingEvents = []; protected function raise($event) { $this->pendingEvents[] = $event; } public function releaseEvents() { $events = $this->pendingEvents; $this->pendingEvents = []; return $events; } }
  • 75. trait EventGenerator { protected $pendingEvents = []; protected function raise($event) { $this->pendingEvents[] = $event; } public function releaseEvents() { $events = $this->pendingEvents; $this->pendingEvents = []; return $events; } }
  • 76. trait EventGenerator { protected $pendingEvents = []; protected function raise($event) { $this->pendingEvents[] = $event; } public function releaseEvents() { $events = $this->pendingEvents; $this->pendingEvents = []; return $events; } }
  • 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. 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. 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. 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. 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. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC EVENT DISPATCHING
  • 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. 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. 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. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC THE FULL COMMAND HANDLER Heads Up...
  • 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. 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. 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. 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. 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. 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. 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. 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. 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. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC MemberRepliedToThread NOTIFY THREAD SUBSCRIBERS w NOTIFY TAGGED USERS COMPLEX SEQUENCE
  • 97. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC MemberRepliedToThread NOTIFY THREAD SUBSCRIBERS NOTIFY TAGGED USERS COMPLEX SEQUENCE
  • 98. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC MemberRepliedToThread NotifyThreadSubscribers NotifyTaggedUsers COMPLEX SEQUENCE
  • 99. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC MEMBER IS NOTIFIED COMPLEX SEQUENCE SEND NOTIFICATION EMAIL
  • 100. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC MEMBER IS NOTIFIED COMPLEX SEQUENCE SEND NOTIFICATION EMAIL
  • 101. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC MemberNotificationSent COMPLEX SEQUENCE SEND NOTIFICATION EMAIL
  • 102. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC MemberNotificationSent COMPLEX SEQUENCE SEND NOTIFICATION EMAIL
  • 103. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC MemberNotificationSent COMPLEX SEQUENCE SendNotificationEmail
  • 104. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC DOMAIN EVENTS MemberRepliedToThread NotifyThreadSubscribers SendNotificationEmail NotifyTaggedMembers EVENTS LISTENERS MemberNotificationSent
  • 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. Laravel.IO, A Use Case Architecture By Shawn McCool Laracon 2014 in NYC DOMAIN-DRIVEN DESIGN
  • 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. 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. Tickets are available at http://Laracon.EU
  • 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