Discovering unknown with EventStorming ConFoo

Discovering unknown with EventStorming ConFoo

34be88398f623c109b61d23e8215bd23?s=128

Mariusz Gil

March 14, 2019
Tweet

Transcript

  1. Mariusz Gil DISCOVERING UNKNOWN WITH @mariuszgil

  2. None
  3. https://www.tripled.io/img/DDD-books.jpg

  4. CAPTURE The knowledge @mariuszgil

  5. Embed Into code @mariuszgil

  6. Protect From the world @mariuszgil

  7. The critical complexity of most software projects is in understanding

    the domain itself Eric Evans @mariuszgil
  8. Given… when… then… @mariuszgil

  9. Initial idea

  10. Reality

  11. None
  12. None
  13. Meet& tELL your STORY @mariuszgil

  14. None
  15. None
  16. @mariuszgil

  17. @mariuszgil

  18. Reservation requested @mariuszgil

  19. Reservation requested Reservation accepted @mariuszgil

  20. Reservation requested Reservation accepted Availability and Limits checked @mariuszgil

  21. Reservation requested Reservation accepted Availability and Limits checked @mariuszgil

  22. Reservation requested Reservation accepted Availability and Limits checked @mariuszgil

  23. Reservation requested Reservation accepted Availability and Limits checked customer @mariuszgil

  24. Reservation requested Reservation accepted Availability and Limits checked customer Reservation

    rejected How to handle rejections? @mariuszgil
  25. Reservation requested Reservation accepted Availability and Limits checked customer Reservation

    rejected How to handle rejections? Similar offer Proposed @mariuszgil
  26. Reservation requested Reservation accepted Availability and Limits checked customer Reservation

    rejected How to handle rejections? Similar offer Proposed agent @mariuszgil
  27. Airline ticket Api gateway Reservation requested Reservation accepted Availability and

    Limits checked customer Reservation rejected How to handle rejections? Similar offer Proposed agent @mariuszgil
  28. Airline ticket Api gateway Reservation requested Availability and Limits checked

    customer Reservation rejected How to handle rejections? Similar offer Proposed agent Email gateway Reservation accepted @mariuszgil
  29. Airline ticket Api gateway Reservation requested Availability and Limits checked

    customer Reservation rejected How to handle rejections? Similar offer Proposed agent Email gateway Confirmation Delivered Reservation accepted @mariuszgil
  30. Airline ticket Api gateway Reservation requested Availability and Limits checked

    customer Reservation rejected How to handle rejections? Similar offer Proposed agent Email gateway Confirmation Delivered Reservation accepted $ $ @mariuszgil
  31. Airline ticket Api gateway Reservation requested Availability and Limits checked

    customer Reservation rejected How to handle rejections? Similar offer Proposed agent Email gateway Confirmation Delivered Reservation accepted $ $ How to handle service Downtimes? @mariuszgil
  32. Airline ticket Api gateway Reservation requested Availability and Limits checked

    customer Reservation rejected How to handle rejections? Similar offer Proposed agent Email gateway Confirmation Delivered Reservation accepted $ $ How to handle service Downtimes? Some customers Have phones Only! @mariuszgil
  33. None
  34. None
  35. None
  36. None
  37. None
  38. None
  39. None
  40. None
  41. Bad decisions Cost a lot… @mariuszgil

  42. None
  43. None
  44. None
  45. None
  46. None
  47. None
  48. It’s DEVELoper (mis)understanding Not expert knowledge That get’s released in

    production Alberto Brandolini @mariuszgil
  49. Big picture Event storming @mariuszgil

  50. Design level Event storming @mariuszgil

  51. Aggregate Event Actor Command / Decision Read model External System

    Policy @mariuszgil Command Query
  52. @mariuszgil https://docs.axoniq.io/reference-guide/v/3.3/part-i-getting-started/architecture-overview

  53. Payment Registered Loyalty points registered Loyalty points calculated Upgrade limits

    reached Account upgraded to higher status @mariuszgil
  54. Payment Registered Loyalty points registered Loyalty points calculated Upgrade limits

    reached Account upgraded to higher status Register loyalty points @mariuszgil
  55. Payment Registered Loyalty points registered Loyalty points calculated Upgrade limits

    reached Account Status upgraded Register loyalty points Upgrade account status @mariuszgil
  56. Payment Registered Loyalty points registered Loyalty points calculated Upgrade limits

    reached Account Status upgraded Register loyalty points Upgrade account status required points Levels Account upgrading policy @mariuszgil
  57. Payment Registered Loyalty points registered Loyalty points calculated Upgrade limits

    reached Account Status upgraded Register loyalty points Upgrade account status required points Levels Account upgrading policy Reservations and payments history c.service @mariuszgil
  58. Payment Registered Loyalty points calculated Upgrade limits reached Account Status

    upgraded Upgrade account status required points Levels Account upgrading policy Loyalty account Loyalty points registered Register loyalty points Reservations and payments history c.service @mariuszgil
  59. Payment Registered Loyalty points calculated Upgrade limits reached Account Status

    upgraded Upgrade account status required points Levels Account upgrading policy Loyalty account Loyalty points registered Register loyalty points Reservations and payments history c.service @mariuszgil
  60. Outcomes @mariuszgil

  61. Possible implementation Solution @mariuszgil There are many of them!!!!!!

  62. business domain logic application logic infrastructure

  63. business logic application logic infrastructure

  64. business logic application logic infrastructure aggregate Event publishing command domain

    event
  65. @Entity // Mark this aggregate as a JPA Entity public

    class MyAggregate { @Id private String id; // fields containing state... @CommandHandler public MyAggregate(CreateMyAggregateCommand command) { // ... update state apply(new MyAggregateCreatedEvent(...)); } // constructor needed by JPA protected MyAggregate() { } } Event Command / Decision
  66. domain event domain event business logic application logic infrastructure domain

    event aggregate domain event event sourcing
  67. public class MyAggregateRoot { @AggregateIdentifier private String aggregateIdentifier; // fields

    containing state... @CommandHandler public MyAggregateRoot(CreateMyAggregate cmd) { apply(new MyAggregateCreatedEvent(cmd.getId())); } // constructor needed for reconstruction protected MyAggregateRoot() { } @EventSourcingHandler private void handleMyAggregateCreatedEvent(MyAggregateCreatedEvent event) { // make sure identifier is always initialized properly this.aggregateIdentifier = event.getMyAggregateIdentifier(); // ... update state } } Aggregate
  68. domain event domain event domain event domain event business logic

    application logic infrastructure domain event domain event command domain event policy process managers
  69. business logic application logic infrastructure domain event command saga domain

    event command domain event Compensate command policy policy
  70. public class OrderManagementSaga { private boolean paid = false; private

    boolean delivered = false; @Inject private transient CommandGateway commandGateway; @StartSaga @SagaEventHandler(associationProperty = "orderId") public void handle(OrderCreatedEvent event) { // client generated identifiers ShippingId shipmentId = createShipmentId(); InvoiceId invoiceId = createInvoiceId(); // associate the Saga with these values, before sending the commands SagaLifecycle.associateWith("shipmentId", shipmentId); SagaLifecycle.associateWith("invoiceId", invoiceId); // send the commands commandGateway.send(new PrepareShippingCommand(...)); commandGateway.send(new CreateInvoiceCommand(...)); } @SagaEventHandler(associationProperty = "shipmentId") public void handle(ShippingArrivedEvent event) { delivered = true; if (paid) { SagaLifecycle.end(); } } @SagaEventHandler(associationProperty = "invoiceId") public void handle(InvoicePaidEvent event) { paid = true; if (delivered) { SagaLifecycle.end(); } } // ... } Reactive Policy
  71. read model business logic application logic infrastructure read models domain

    event domain event domain event domain event read model read model read model
  72. business logic application logic infrastructure

  73. business logic application logic infrastructure

  74. business logic application logic infrastructure BUS Event

  75. Event Command / Decision Event Event Aggregate

  76. public class MyCommandComponentTest { private FixtureConfiguration<MyAggregate> fixture; @Before public void

    setUp() { fixture = new AggregateTestFixture<>(MyAggregate.class); } @Test public void testFirstFixture() { fixture.given(new MyEvent(1)) .when(new TestCommand()) .expectSuccessfulHandlerExecution() .expectEvents(new MyEvent(2)); /* } } Event Command / Decision Event Event Aggregate Given When Then
  77. Command / Decision Read model Event Event Given When Then

  78. Event Command / Decision Aggregate Read model Given When Then

    Event
  79. DDD is not for you? @mariuszgil

  80. Event Command / Decision Aggregate Read model Reactive Policy

  81. Event Command / Decision Aggregate Read model Reactive Policy Record

    Inserted / Changed / Deleted Insert / Update / Delete / Truncate / … Record / Table Select / View Trigger / Procedure
  82. Takeaways @mariuszgil

  83. Big Picture Events Processes & Flows Hot Spots Systems Boundaries

    People @mariuszgil
  84. Process Modeling Commands Policies Read Models Value Propositions Personas Metrics

    & Alerts @mariuszgil
  85. Software Design Aggregates Policies Reactive Logic Read Models @mariuszgil

  86. Communication! @mariuszgil

  87. Building common understanding @mariuszgil

  88. From production session

  89. From production session

  90. From alberto bandolino workshop

  91. From production session

  92. Software development is learning process Working code is a side

    effect Alberto Brandolini @mariuszgil
  93. None
  94. What’s next? @mariuszgil

  95. None
  96. None
  97. None
  98. THANK YOU! @mariuszgil