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

Implementing DDD in your project

Implementing DDD in your project

This presentation shows a simple approach of a DDD implementation in your project.
Was exposed in PHP Barcelona first Monthly Talk (Barcelona)

0d83f514dfdd88bd9315481cee61fda8?s=128

Sergio Moya

June 11, 2014
Tweet

Transcript

  1. Sergio Moya @soyelsergillo IN

  2. @SOYELSERGILLO GITHUB.COM/SMOYA Backend Engineer at Social Point ! DDD Fan

    ! Hip Hop Culture lover ! Badaloní (from Badalona) SERGIO
  3. WHAT

  4. MODEL 3 2 4 1 DOMAIN CONTEXT UBIQUITOUS

  5. UBIQUITOUS

  6. KNOW YOUR UBIQUITOUS LANGUAGE

  7. The Lead of the Backend engineers team has decided to

    split the team into smaller two-member teams. ! Each team will develop a different component. ! Our team will develop the Payment Component
  8. None
  9. THE

  10. OUR

  11. None
  12. GENERATING

  13. THE

  14. THE

  15. AND

  16. THE

  17. SERVICE ORM CONTRO LLER REPOSIT ORY DB MANAGER YOUR

  18. THIS IS WAR!

  19. BUT YOU WANT THIS

  20. BUT WE WANT THIS TODAY YOU WILL GET THIS

  21. LET’S

  22. …⋯ SRC …⋯ …⋯ PAYMENTBUNDLE …⋯ COMPONENT PAYMENT BUNDLE FILE

  23. OUR

  24. OUR

  25. OUR

  26. We are recording Events!

  27. BUT WHAT IS A DOMAIN EVENT?

  28. “CAPTURES

  29. DOMAIN

  30. DOMAIN

  31. DOMAIN

  32. DOMAIN

  33. REMEMBER A CUSTOMER CAN ORDER A PRODUCT ! A CUSTOMER

    CAN PAY AN ORDER
  34. OUR

  35. OUR

  36. public function pay(Money $money)! {! try {! if (!$this->product->getPrice()->isEqualTo($money)) {!

    throw new OrderException('The Order amount is not satisfied');! }! $this->product->deliver($this->customer);! $this->status = OrderStatus::create(OrderStatus::ORDER_PAID);! } catch (\Exception $e) {! $this->status = OrderStatus::create(OrderStatus::ORDER_FAILED);! }! return $this->status;! } OUR
  37. WHAT

  38. WHAT

  39. interface OrderRepository! {! public function exists($id);! ! public function find($id,

    $customerId);! ! public function findByCustomerId($customerId);! ! public function save($id, $productId, $customerId, $status = 1);! ! public function remove($id);! ! public function removeByCustomerId($customerId);! ! public function clearAll();! }! OUR
  40. OK,

  41. OK,

  42. None
  43. public function buyProductAction(Request $request)! {! $customer = new Customer($request->request->get('customerId'));! !

    $productRepository = $this->get('tato.payment.product_respository');! $product = $productRepository->find($request->request->get('productId'));! ! $order = $customer->order($product);! ! $paid = new Money(! $request->request->get('paid'), ! $request->request->get(‘currency')! );! $status = $order->pay($paid);! ! $this->get(‘tato.payment.order_repository')->save(! ! ! $order->getId(), ! $product, ! $customer->getId(), ! $status->getStatus()! );! ! return new JsonResponse(array('status' => $status->getStatus()));! }! } A
  44. public function buyProductAction(Request $request)! {! $customer = new Customer($request->request->get('customerId'));! !

    $productRepository = $this->get('tato.payment.product_respository');! $product = $productRepository->find($request->request->get('productId'));! ! $order = $customer->order($product);! ! $paid = new Money(! $request->request->get('paid'), ! $request->request->get(‘currency')! );! $status = $order->pay($paid);! ! $this->get(‘tato.payment.order_repository')->save(! ! ! $order->getId(), ! $product, ! $customer->getId(), ! $status->getStatus()! );! ! return new JsonResponse(array('status' => $status->getStatus()));! }! } A
  45. LET’S

  46. TAKE A PIECE OF CQRS COMMAND QUERY RESPONSIBILITY SEGREGATION

  47. Any method that mutates state. Any method that returns a

    value. COMMAND QUERY COMMAND
  48. class BuyProductCommand! {! public $customerId;! ! public $productId;! ! public

    $paid;! ! public $currency;! ! public function __construct($customerId, $productId, $paid, $currency)! {! $this->customerId = $customerId;! $this->productId = $productId;! $this->paid = $paid;! $this->currency = $currency;! } ! } THE
  49. public function handle(BuyProductCommand $command)! {! $customer = new Customer($command->customerId);! $product

    = $this->productRepository->find($command->productId);! ! $order = $customer->order($product);! $status = $order->pay(new Money($command->paid, $command->currency));! ! $events = $customer->getRecordedEvents();! ! // @todo do something with this events! ! $this->orderRepository->setOrder(! $command->gatewayName,! $order->getId(),! $command->customerId,! $status->getStatus()! );! ! return $order;! } A
  50. COMPONENT

  51. WE

  52. IMAGINE

  53. FILE

  54. WE

  55. OUR

  56. CONSTRUCT

  57. INFRASTRUCTURE

  58. SERVICES services:! tato.payment.order_repository:! class: Tato\Component\Game\CustomOrderRepository! arguments:! - @doctrine.orm.entity_manager! ! tato.payment.product_repository:!

    class: Tato\Component\Game\Product\CustomProductRepository! arguments:! - @doctrine.orm.entity_manager! ! tato.payment.command.handler.buy_product:! class: Tato\Component\Payment\Command\BuyProductCommandHandler! arguments:! order_repository: @tato.payment.order_repository! product_repository: @tato.payment.product_repository!
  59. AND

  60. AND

  61. PAYMENT

  62. public function buyProductAction(Request $request)! {! $customer = new Customer($request->request->get('customerId'));! !

    $productRepository = $this->get('tato.payment.product_respository');! $product = $productRepository->find($request->request->get('productId'));! ! $order = $customer->order($product);! ! $paid = new Money(! $request->request->get('paid'), ! $request->request->get(‘currency')! );! $status = $order->pay($paid);! ! $this->get(‘tato.payment.order_repository')->save(! ! ! $order->getId(), ! $product, ! $customer->getId(), ! $status->getStatus()! );! ! return new JsonResponse(array('status' => $status->getStatus()));! }! } THE
  63. OUR

  64. BE HEXAGONAL!

  65. ENJOY DDD

  66. LINKS

  67. QUESTIONS?

  68. Sergio Moya @soyelsergillo THANKS I’M