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."

Avatar for Hugo Henrique

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); // ... } }