Upgrade to Pro — share decks privately, control downloads, hide ads and more …

CommandBus

 CommandBus

Um overview do CommandBus e um pequeno caso de uso de como aplica-lo para obter uma aplicação menos desacoplada.

"O primeiro passo para uma arquitetura hexagonal."

Hugo Henrique

August 19, 2017
Tweet

More Decks by Hugo Henrique

Other Decks in Programming

Transcript

  1. 1 <?php 2 namespace App\Http; 3 4 use MyLovedFramework\Controller; 5

    use MyLovedFramework\Request; 6 7 class BookController extends Controller 8 { 9 // ... 10 public function purchaseAction(Request $request) 11 { 12 if ($bookId = $request->query->get('bookId')) { 13 throw new \InvalidArgumentException(sprintf('The book %s cannot be found', $bookId)); 14 } 15 16 try { 17 $this->entityManager->beginTransaction(); 18 19 $book = $this->bookRepository->find($bookId); 20 21 $buyer = $this->currentSession()->user(); 22 $buyer->purchase($book); 23 24 $this->userRepository->persist($buyer); 25 26 $this->logger->log('info', sprintf('The book %s was purchased by user %s', $bookId, $buyer->getId())); 27 28 $this->mailer->send( 29 $buyer->getEmailAddress(), 30 'Your purchase is being processed', 31 'template_purchase.html' 32 ); 33 34 $this->entityManager->commit(); 35 36 return new Response(200, 'You purchase has been processed!'); 37 } catch (\Exception $e) { 38 $this->entityManager->rollback(); 39 $this->logger->log('error', $e->getMessage()); 40 return new Response(500, 'Problem to processing request'); 41 } 42 } 43 }
  2. 1 <?php 2 namespace App\Http; 3 4 use MyLovedFramework\Controller; 5

    use MyLovedFramework\Request; 6 7 class BookController extends Controller 8 { 9 // ... 10 public function purchaseAction(Request $request) 11 { 12 if ($bookId = $request->query->get('bookId')) { 13 throw new \InvalidArgumentException(sprintf('The book %s cannot be found', $bookId)); 14 } 15 16 try { 17 $this->entityManager->beginTransaction(); 18 19 $book = $this->bookRepository->find($bookId); 20 21 $buyer = $this->currentSession()->user(); 22 $buyer->purchase($book); 23 24 $this->userRepository->persist($buyer); 25 26 $this->logger->log('info', sprintf('The book %s was purchased by user %s', $bookId, $buyer->getId())); 27 28 $this->mailer->send( 29 $buyer->getEmailAddress(), 30 'Your purchase is being processed', 31 'template_purchase.html' 32 ); 33 34 $this->entityManager->commit(); 35 36 return new Response(200, 'You purchase has been processed!'); 37 } catch (\Exception $e) { 38 $this->entityManager->rollback(); 39 $this->logger->log('error', $e->getMessage()); 40 return new Response(500, 'Problem to processing request'); 41 } 42 } 43 } "650"$01-".&/50 "0'3".&803,
  3. 1 <?php 2 namespace App\Http; 3 4 use MyLovedFramework\Controller; 5

    use MyLovedFramework\Request; 6 7 class BookController extends Controller 8 { 9 // ... 10 public function purchaseAction(Request $request) 11 { 12 if ($bookId = $request->query->get('bookId')) { 13 throw new \InvalidArgumentException(sprintf('The book %s cannot be found', $bookId)); 14 } 15 16 try { 17 $this->entityManager->beginTransaction(); 18 19 $book = $this->bookRepository->find($bookId); 20 21 $buyer = $this->currentSession()->user(); 22 $buyer->purchase($book); 23 24 $this->userRepository->persist($buyer); 25 26 $this->logger->log('info', sprintf('The book %s was purchased by user %s', $bookId, $buyer->getId())); 27 28 $this->mailer->send( 29 $buyer->getEmailAddress(), 30 'Your purchase is being processed', 31 'template_purchase.html' 32 ); 33 34 $this->entityManager->commit(); 35 36 return new Response(200, 'You purchase has been processed!'); 37 } catch (\Exception $e) { 38 $this->entityManager->rollback(); 39 $this->logger->log('error', $e->getMessage()); 40 return new Response(500, 'Problem to processing request'); 41 } 42 } 43 } #"*9"$0&4§0
  4. 1 <?php 2 namespace App\Http; 3 4 use MyLovedFramework\Controller; 5

    use MyLovedFramework\Request; 6 7 class BookController extends Controller 8 { 9 // ... 10 public function purchaseAction(Request $request) 11 { 12 if ($bookId = $request->query->get('bookId')) { 13 throw new \InvalidArgumentException(sprintf('The book %s cannot be found', $bookId)); 14 } 15 16 try { 17 $buyer = $this->currentSession()->user(); 18 $book = $this->bookRepository->find($bookId); 19 20 $this->purchaseService->persist($book, $buyer); 21 22 } catch (\Exception $e) { 23 return new Response(500, 'Problem to processing request'); 24 } 25 26 return new Response(200, 'You purchase has been processed!'); 27 } 28 }
  5. 1 <?php 2 namespace App\Http; 3 4 use MyLovedFramework\Controller; 5

    use MyLovedFramework\Request; 6 7 class BookPurchaseService extends Controller 8 { 9 // ... 10 public function purchase(Book $book, User $buyer) 11 { 12 try { 13 $this->entityManager->beginTransaction(); 14 15 $buyer->purchase($book); 16 17 $this->userRepository->persist($buyer); 18 19 $this->entityManager->commit(); 20 21 $this->logger->log(‘info', 'The book was purchased'); 22 23 $this->mailer->send( 24 $buyer->getEmailAddress(), 25 'Your purchase is being processed', 26 'template_purchase.html' 27 ); 28 29 } catch (\Exception $e) { 30 $this->entityManager->rollback(); 31 $this->logger->log('error', $e->getMessage()); 32 return new Response(500, 'Problem to processing request'); 33 } 34 35 return new Response(200, 'You purchase has been processed!'); 36 } 37 }
  6. 1 <?php 2 namespace App\Http; 3 4 use MyLovedFramework\Controller; 5

    use MyLovedFramework\Request; 6 7 class BookPurchaseService extends Controller 8 { 9 public function purchase(Book $book, User $buyer) 10 { 11 } 12 13 public function anotherMethod() 14 { 15 } 16 17 public function chargeback($orderId) 18 { 19 } 20 }
  7. 1 <?php 2 namespace App\Http; 3 4 use MyLovedFramework\Controller; 5

    use MyLovedFramework\Request; 6 7 class BookPurchaseService extends Controller 8 { 9 // ... 10 public function purchase(Book $book, User $buyer) 11 { 12 try { 13 $this->entityManager->beginTransaction(); 14 15 $buyer->purchase($book); 16 17 $this->userRepository->persist($buyer); 18 19 $this->entityManager->commit(); 20 21 $this->logger->log(‘info', 'The book was purchased'); 22 23 $this->mailer->send( 24 $buyer->getEmailAddress(), 25 'Your purchase is being processed', 26 'template_purchase.html' 27 ); 28 29 } catch (\Exception $e) { 30 $this->entityManager->rollback(); 31 $this->logger->log('error', $e->getMessage()); 32 return new Response(500, 'Problem to processing request'); 33 } 34 35 return new Response(200, 'You purchase has been processed!'); 36 } 37 } 0.¬50%0$0/5*/6"$0..6*5"43&410/4"#*-*%"%&4 4*/(-&3&410/4"#*-*5:
  8. 1 <?php 2 namespace App\Http; 3 4 use MyLovedFramework\Controller; 5

    use MyLovedFramework\Request; 6 7 class BookPurchaseService extends Controller 8 { 9 public function purchase(Book $book, User $buyer) 10 { 11 } 12 13 public function anotherMethod() 14 { 15 } 16 17 public function chargeback($orderId) 18 { 19 } 20 } "$-"44&%&4&37*ª0$0/5*/6"7*0-"/%0431
  9. $0.."/%*44*.1-&"%50 %"5"53"/4'&30#+&$5 1 <?php 2 namespace App\Domain\Member; 3 4 class

    RegisterMember 5 { 6 private $emailAddress; 7 private $password; 8 9 public function __construct(string $emailAddress, string $password) 10 { 11 $this->emailAddress = $emailAddress; 12 $this->password = $password; 13 } 14 15 public function emailAddress() : string 16 { 17 return $this->emailAddress; 18 } 19 20 public function password() : string 21 { 22 return $this->password; 23 } 24 }
  10. <?php namespace App\Http; use MyLovedFramework\Controller; use MyLovedFramework\Request; class BookController extends

    Controller { // ... public function purchaseAction(Request $request) { $userId = $this->session->currentUser()->id(); $bookId = $request->get('bookId'); $command = new PurchaseBook($bookId, $userId); // ... } }
  11. <?php namespace App\Handler; class PuchaseBookHandler { public function __invoke(PurchaseCommand $command)

    { try { $this->entityManager->beginTransaction(); $buyer = $this->userRepository->find($command->buyerId()); $book = $this->bookRepository->find($command->bookId()); $buyer->purchase($book); $this->userRepository->persist($buyer); $this->entityManager->commit(); $this->mailer->send( $buyer->getEmailAddress(), 'Your purchase is being processed', 'template_purchase.html' ); // Logs the purchase } catch (\Exception $e) { $this->entityManager->rollback(); // Logs when error is raised } } }
  12. <?php namespace Infrastructure\Command; class SignUpUserConsoleCommand extends ConsoleCommand { public function

    execute(Input $input) { $command = new SignUp( $input->getArgument('emailAddress'), $input->getArgument('password') ); $this->commandBus()->handle($command); } }
  13. <?php namespace App\Handler; class PuchaseBookHandler { public function __invoke(PurchaseCommand $command)

    { try { $this->entityManager->beginTransaction(); $buyer = $this->userRepository->find($command->buyerId()); $book = $this->bookRepository->find($command->bookId()); $buyer->purchase($book); $this->userRepository->persist($buyer); $this->entityManager->commit(); $this->mailer->send( $buyer->getEmailAddress(), 'Your purchase is being processed', 'template_purchase.html' ); // Logs the purchase } catch (\Exception $e) { $this->entityManager->rollback(); // Logs when error is raised } } }
  14. <?php class CommandBus { private $handlerMap; public function __construct($handlerMap =

    []) { $this->handlerMap = $handlerMap; } public function handle($command) { // .. $this->handlerMap(get_class($command))->handle($command); // .. } } $handler = new PurchaseBookHandler(); $handlerMap = [ 'PurchaseBookCommand' => $handler ]; $command = new PurchaseBookCommand(); $commandBus = new CommandBus($handlerMap); $commandBus->handle($command);
  15. <?php class AnExampleMiddleware implements Middleware { public function execute($command, callable

    $next) { // .. // .. $next($command); } } "(03"10%&.04&9&$65"3/07"4"ª¸&4"/5&4&%&10*4 %"&9&$6ª§0%&6.$0."/%0
  16. <?php namespace League\Tactician\Doctrine\ORM; use Doctrine\ORM\EntityManagerInterface; use League\Tactician\Middleware; class TransactionMiddleware implements

    Middleware { // ... public function execute($command, callable $next) { $this->entityManager->beginTransaction(); try { $returnValue = $next($command); $this->entityManager->flush(); $this->entityManager->commit(); } catch (Exception $e) { $this->rollbackTransaction(); throw $e; } catch (Throwable $e) { $this->rollbackTransaction(); throw $e; } return $returnValue; } // ... } 6.$"40%&6401"3"53"/4"ª¸&4$0.%0$53*/&03.
  17. 1 <?php 2 namespace App\Http; 3 4 use MyLovedFramework\Controller; 5

    use MyLovedFramework\Request; 6 7 class BookController extends Controller 8 { 9 // ... 10 public function purchaseAction(Request $request) 11 { 12 if ($bookId = $request->query->get('bookId')) { 13 throw new \InvalidArgumentException(sprintf('The book %s cannot be found', $bookId)); 14 } 15 16 try { 17 $this->entityManager->beginTransaction(); 18 19 $book = $this->bookRepository->find($bookId); 20 21 $buyer = $this->currentSession()->user(); 22 $buyer->purchase($book); 23 24 $this->userRepository->persist($buyer); 25 26 $this->logger->log('info', sprintf('Book %s was purchased', $bookId)); 27 28 $this->mailer->send( 29 $buyer->getEmailAddress(), 30 'Your purchase is being processed', 31 'template_purchase.html' 32 ); 33 34 $this->entityManager->commit(); 35 36 return new Response(200, 'You purchase has been processed!'); 37 } catch (\Exception $e) { 38 $this->entityManager->rollback(); 39 $this->logger->log('error', $e->getMessage()); 40 return new Response(500, 'Problem to processing request'); 41 } 42 } 43 } <?php namespace App\Http; use MyLovedFramework\Controller; use MyLovedFramework\Request; class BookController extends Controller { // ... public function purchaseAction(Request $request) { $userId = $this->session->currentUser()->id(); $bookId = $request->get('bookId'); $command = new PurchaseBook($bookId, $userId); $this->commandHandler->handle($command); // ... } }