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

Domain-Driven Design (Tutorial)

Domain-Driven Design (Tutorial)

Tutorial »Domain-Driven Design«

Henning Schwentner

September 26, 2023
Tweet

More Decks by Henning Schwentner

Other Decks in Programming

Transcript

  1. Morning Afternoon Wor ksho p Wor ksho p Wor ksho

    p Wor ksho p Wor ksho p Wor ksho p Wor ksho p
  2. Ubiquitous Language Building Blocks Domain Event Aggregate Entity Value Object

    Bounded Context Strategic Design Context Mapping Collaborative Modeling Domain Expert Event Storming Modeling in Code Domain Storytelling Core Domain Domain Model
  3. Microservices CQRS Hexagonal Architecture Agile Event Sourcing Extreme Programming Scrum

    Cloud Self-Contained Systems Verticals Clean Architecture DevOps AWS Azure Onion Architecture
  4. Programming Languages My Questions My life as a developer My

    experiences using DDD My wishes regarding the training family My first computer
  5. PUTS NAVIGATING OFFICER CAPTAIN ASKS FOR 7 SHIP SILHOUETTE ON

    CARTO- GRAPHER SOUNDING SHIP DEPTH MEASURES 1 SENDS 2 TO CALCULATES 3 DRAW S 4 SENDS 5 DEPTH MAP TO MOVES & TURNS 8 SHIP SILHOUETTE TO FIND 9 DISCUSSES WITH 6 ROUTE ROUTE DEPTH MAP DEPTH MAP DEPTH (RAW) ROUTE CONTOUR LINES
  6. ?

  7. PUTS NAVIGATING OFFICER CAPTAIN ASKS FOR 7 SHIP SILHOUETTE ON

    CARTO- GRAPHER SOUNDING SHIP DEPTH MEASURES 1 SENDS 2 TO CALCULATES 3 DRAW S 4 SENDS 5 DEPTH MAP TO MOVES & TURNS 8 SHIP SILHOUETTE TO FIND 9 DISCUSSES WITH 6 ROUTE ROUTE DEPTH MAP DEPTH MAP DEPTH (RAW) ROUTE CONTOUR LINES
  8. MOVES & TURNS 8 SHIP SILHOUETTE TO FIND ROUTE NAUTICAL

    OFFICER «Entity» Silhouette move() turn()
  9. BIG

  10. #

  11. #

  12. PUTS NAVIGATING OFFICER CAPTAIN ASKS FOR 7 SHIP SILHOUETTE ON

    CARTO- GRAPHER SOUNDING SHIP DEPTH MEASURES 1 SENDS 2 TO CALCULATES 3 DRAW S 4 SENDS 5 DEPTH MAP TO MOVES & TURNS 8 SHIP SILHOUETTE TO FIND 9 DISCUSSES WITH 6 ROUTE ROUTE DEPTH MAP DEPTH MAP DEPTH (RAW) ROUTE CONTOUR LINES DEPTH MEASURE- MENT MANEUVER PLANNING
  13. LEGT NAUTIKER KAPITÄN FRAGT NACH 7 SCHIFFS- SILHOUETTE AUF PEILDIENST

    PEILSCHIFF TIEFE PEILT 1 SENDET 2 AN BERECHNET 3 ERZ EUGT 4 SENDET 5 PEILPLAN AN VERSCHIEBT & DREHT 8 SCHIFFS- SILHOUETTE UND FINDET 9 MELDET AN 6 ROUTE ROUTE PEILPLAN PEILPLAN TIEFEN- ZAHLEN ROUTE TIEFENLINIEN
  14. @hschwentner DEPTH MAP HANDS OVER NAUTICAL OFFICER CARTOGRAPHER TO “The

    cartographer sends the depth map to the nautical officer” SENDS
  15. @hschwentner ßDraw here Leave some empty space there à Annota3ons

    and varia3ons Preconditions and assumptions Name of the Domain Story
  16. ACTORS ONCE/ WORK OBJECTS SEVERAL TIMES PUTS NAUTICAL OFFICER 7

    SHIP SILHOUETTE MOVES & TURNS 8 SHIP SILHOUETTE
  17. Scenarios Maneuver Planning – The Happy Path Maneuver Planning –

    Storm Flooding Expected Maneuver Planning – All Berths Full
  18. @hschwentner A Day at the Beach " Sea Level #

    Kite Level ☁ Cloud Level % Fish Level & Clam Level Foto: Dennis Hamilton/flickr/CC BY 2.0 Alistair Cockburn
  19. ?

  20. ?

  21. ?

  22. ?

  23. !

  24. #

  25. #

  26. PUTS NAVIGATING OFFICER CAPTAIN ASKS FOR 7 SHIP SILHOUETTE ON

    CARTO-GRAPHER SOUNDING SHIP DEPTH MEASURES 1 SENDS 2 TO CALCULATES 3 DRAW S 4 SENDS 5 DEPTH MAP TO MOVES & TURNS 8 SHIP SLHOETTE TO FIND 9 DISCUSSES WITH 6 ROUTE ROUTE DEPTH MAP DEPTH MAP DEPTH (RAW) ROUTE CONTOUR LINES DEPTH MEASURE- MENT MANEUVER PLANNING
  27. CUSTOMER TELLS WISH FOR 1 SALES- PERSON SIGNS TO GIVES

    FOR CONTRACT 3 RISK MANAGER CONTRACT PASSES ON TO 4 CONTRACT VO TES CHECKS CALCU LATES 5 6 7 CALCU- LATES TO 8 2 CAR CREDIT RATING INSTALLMENT CAR RESALE VALUE CONTRACT
  28. 26.09.23 //// Seite 375 WPS – Workplace Solutions CUSTOMER TELLS

    WISH FOR 1 SALES- PERSON SIGNS TO GIVES FOR CONTRACT 3 RISK MANAGER CONTRACT PASSES ON TO 4 CONTRACT VOTES CHECKS CALCULATES 5 6 7 CALCU- LATES TO 8 2 CAR CREDIT RATING INSTALLMENT CAR RESALE VALUE CONTRACT SALES RISK ASSESSMENT
  29. 26.09.23 //// Seite 381 WPS – Workplace Solutions Common heuristics:

    § Points of no Return (persistent work results) § Boundaries within the process § State changes, that affect the “nature” of a work object (e.g. “contract legally binding,” “shopping cart ordered”) § Departments of the organisation § Contextual language § Different usage of work objects § Triggers at different points in time § NOT: by work objects! HOW TO CUT THE DOMAIN? Foto: Wikipedia/PD-ScottForesman
  30. CUSTOMER TELLS WISH FOR 1 SALESPERSON SIGNS TO GIVES FOR

    CONTRACT 3 RISK MANAGER CONTRACT PASSES ON TO 4 CONTRACT VO TES CHECKS CALCU LATES 5 6 7 CALCU- LATES TO 8 2 CAR CREDIT RATING INSTALLMENT CAR RESALE VALUE CONTRACT SALES RISK ASSESSMENT
  31. CUSTOMER TELLS WISH FOR 1 SALESPERSON SIGNS TO GIVES FOR

    CONTRACT 3 RISK MANAGER CONTRACT PASSES ON TO 4 CONTRACT VO TES CHECKS CALCU LATES 5 6 7 CALCU- LATES TO 8 2 CAR CREDIT RATING INSTALLMENT CAR RESALE VALUE CONTRACT SALES Group the sentences • Boundary around activites and work objects • Keep actors outside boundaries Give a name to the group RISK ASSESSMENT
  32. @hschwentner Naming Subdomains Express what is done Verbs turned into

    nouns Often: -ing-form Anti-pattern: name of work object as name for subdomain
  33. Indicators: 1) Actor produces result on their own 2) One-way

    informa$on flow 3) Different triggers ($me vs. on demand) 4) Ac$vi$es suppor$ng something that is not in the picture 5) Difference in language 6) Different use of the same thing Ask your domain experts!
  34. 26.09.23 //// Seite 407 WPS – Workplace Solutions BOUNDED CONTEXTS

    FÜR DAS KINO ABLAUF- PLANUNG KARTEN- VERKAUF BUCH- HALTUNG
  35. 26.09.23 //// Seite 429 WPS – Workplace Solutions AND NOW?

    § Core vs Supporting § Event Storming § Taktisches Design § Code/LeasingNinja § Hexagonal/Onion Architecture § Context Mapping § How to split the monolith
  36. 1) How should it be? 2) How is it? 3)

    How to move the “is” to the “ideal”? RISK MANAGE- MENT SALES
  37. 1) How should it be? 1) Domain Re-Discovery 2) “ideal”

    context map 2) How is it? 1) Architecture Analysis 2) As-is context map 3) How to move the “is” to the “ideal”? 1) Compare 2) Create List of Refactorings 4) Do the move 1) Extract a suppor$ng domain to learn 2) Then extract core(s)
  38. old old old old new new new new “just flip

    the lever” 1 2 3 4 5 a.k.a. big bang replacement
  39. 26.09.23 //// Seite 509 WPS – Workplace Solutions § Subdomänen

    § Kern (Core Domain) § Unterstützende (Supporting Domain) § Allgemeine (Generic Domain) § Context Mapping § Shared Kernel § Customer/Supplier § Open-Host-Service § Published Language § Separate Ways § Anticorruption Layer § Conformist STRATEGISCHES DESIGN – WEITERE BEGRIFFE
  40. “There are only two hard things in Computer Science: cache

    invalidation and naming things.” Phil Karlton
  41. “There are only two hard things in Computer Science: cache

    invalidation, naming things, and off-by-one errors.” Phil Karlton
  42. 26.09.23 //// Seite 514 WPS – Workplace Solutions TECHNISCHE SPRACHE

    Auf den Feature Branch pushen? Den Container hochfahren Ich baue dafür ein Interface
  43. 26.09.23 //// Seite 515 WPS – Workplace Solutions TECHNISCHE SPRACHE

    X Class The picture can’t be displayed. Database Server Client O/R-Mapping Inheritance A B Method Interface Linux Windows Eclipse Visual Studio
  44. 26.09.23 //// Seite 516 WPS – Workplace Solutions DOMÄNEN-SPRACHE –

    BEISPIEL SCHIFFAHRT Tiefenzahl Maßstab Silhouette Peilplan Markierung Länge ü.a. Breite Baggertoleranz
  45. 26.09.23 //// Seite 517 WPS – Workplace Solutions DOMÄNEN-SPRACHE –

    BEISPIEL SCHIFFAHRT Container Containernummer 4300 Kran Twistlock Frachtbrief
  46. 26.09.23 //// Seite 518 WPS – Workplace Solutions DOMÄNEN-SPRACHE –

    BEISPIEL SCHACH Brett König Figuren Spieler Schachuhr
  47. 26.09.23 //// Seite 519 WPS – Workplace Solutions DOMÄNEN-SPRACHE –

    BEISPIEL SCHACH II Remis Zugzwang Schachmatt Partie Zug Rochade
  48. 26.09.23 //// Seite 520 WPS – Workplace Solutions Fach- sprache

    Techno Babble ? MOTIVATION ALLGEGENWÄRTIGE SPRACHE
  49. 26.09.23 //// Seite 521 WPS – Workplace Solutions Fach- sprache

    Techno Babble Fach- sprache MOTIVATION ALLGEGENWÄRTIGE SPRACHE
  50. 26.09.23 //// Seite 522 WPS – Workplace Solutions Fach- sprache

    Techno Babble MOTIVATION ALLGEGENWÄRTIGE SPRACHE
  51. 26.09.23 //// Seite 523 WPS – Workplace Solutions Techno Babble

    Fach- sprache MOTIVATION ALLGEGENWÄRTIGE SPRACHE
  52. 26.09.23 //// Seite 524 WPS – Workplace Solutions Fach- sprache

    { Techno Babble } ? MOTIVATION ALLGEGENWÄRTIGE SPRACHE
  53. 26.09.23 //// Seite 525 WPS – Workplace Solutions Fach- sprache

    { Fach- sprache } MOTIVATION ALLGEGENWÄRTIGE SPRACHE
  54. 26.09.23 //// Seite 526 WPS – Workplace Solutions Fach- sprache

    { Fach- sprache } UBIQUITOUS LANGUAGE public class SchiffsSilhouette { public void verschiebe { … } public void drehe { … } … }
  55. 26.09.23 //// Seite 527 WPS – Workplace Solutions GEMEINSAME SPRACHE

    § Fachexperten verstehen keine Begriffe zu technischen Umsetzungen § Fachexperten sprechen den Jargon ihrer Domäne, der für Außenstehende wiederum schwer verständlich sein kann è Eine gemeinsame Sprache ist notwendig! § Welche soll es sein? § Die der Entwickler? § Die der Fachexperten? § Etwas dazwischen? èPrinzip von DDD: „Verwende eine Sprache die auf dem Domänenmodell basiert“
  56. 26.09.23 //// Seite 528 WPS – Workplace Solutions ALLGEGENWÄRTIGE SPRACHE

    § Verwende die gemeinsame Sprache in.. § der Kommunikation § mündlich § schriftlich § grafisch § im Code § Im Grunde genommen überall è Deswegen nennt sich die Sprache allgegenwärtig.
  57. 26.09.23 //// Seite 529 WPS – Workplace Solutions SPRACHE TAUCHT

    NICHT EINFACH AUF § Es braucht Wochen bis Monate... § harter Arbeit § und scharfem Fokus § … um die Schlüsselkonzepte offenzulegen. § Die ersten Wörter einer allgegenwärtigen Sprache kommen üblicherweise direkt aus der Domäne § Im Laufe der Entwicklung werden neue Begriffe definiert und hinzugefügt
  58. 26.09.23 //// Seite 532 WPS – Workplace Solutions UBIQUITOUS LANGUAGE

    – ITERATION 2 Figuren Spieler Nichtmenschlicher Spieler Brett
  59. 26.09.23 //// Seite 533 WPS – Workplace Solutions SPRACHEN SIND

    LEBENDIG § Experimentiere mit alternativen Ausdrucksformen § Das Modell und die Sprache entwickeln sich weiter § Überarbeite dann den Code § Benenne Klassen, Methoden, Module § Entspreche dem neuen Modell § Eine Sprache will gesprochen werden: § Beseitige Unklarheiten durch Konversation
  60. 26.09.23 //// Seite 539 WPS – Workplace Solutions GLOSSAR §

    Fachsprache der Benutzer/Ubiquitous Language •bereits existierende Begriffe •rekonstruierte Begriffe •neue Begriffsbildungen • Wer tut was damit wozu? § Kernkonzepte § Wichtiger am Anfang des Projektes § Oft Wegwerfprodukt
  61. 26.09.23 //// Seite 540 WPS – Workplace Solutions GLOSSAR –

    BEISPIELDOMÄNE SCHACH SPIELER EINE VON ZWEI PERSONEN, DIE FIGUREN AUF DEM BRETT BEWEGT. KÖNIG EINE EINMALIGE FIGUR, DIE NUR EIN FELD PRO ZUG BEWEGT WERDEN KANN. WENN DER KÖNIG SCHACHMATT GESETZT WURDE, IST DAS SPIEL VORBEI. Beschreibung Begriff Oberbegriff Unterscheidungs- merkmale
  62. 26.09.23 //// Seite 541 WPS – Workplace Solutions § Ein

    Team spricht eine eigene Sprache § è Familiensprache, Dialekt § Gleiche Begriffe können (leicht) unterschiedliche Bedeutung haben § Sprache und Modell sind eng gekoppelt JEDER BOUNDED CONTEXT HAT SEINE EIGENE UBIQUITOUS LANGUAGE TIEFEN- MESSUNG PEIL- SCHIFF TIEFEN- ZAHL MARKIER- UNG PEIL- PLAN TIEFEN- ZAHL MANÖVERPLANUNG
  63. 26.09.23 //// Seite 542 WPS – Workplace Solutions JEDER BOUNDED

    CONTEXT HAT SEIN EIGENES GLOSSAR TIEFENZAHL TIEFE AN EINEM BESTIMMTEN ORT UNTER BERÜCKSICHTIGUNG VON EBBE UND FLUT TIEFENZAHL PER ECHOLOT GEMESSENE TIEFE BEI NORMALNULL MANÖVER- PLANUNG TIEFENMESSUNG
  64. 26.09.23 //// Seite 544 WPS – Workplace Solutions KERNBEGRIFFE FÜR

    DAS KINO Saalplan Vorstellung Reservierungs- nummer Kinokarte Saalplanstapel Liste der Reservierungs- nummern Gesamtablauf- plan Tagesablaufplan Film Platz/Sitzplatz Saal/Kinosaal Werbung Veranstaltung Eisverkauf Vorführung ? ?
  65. 26.09.23 //// Seite 545 WPS – Workplace Solutions BOUNDED CONTEXTS

    FÜR DAS KINO Saalplan Vorstellung Reservierungs- nummer Kinokarte Saalplanstapel Liste der Reservierungs- nummern Gesamtablauf- plan Tagesablaufplan Film Platz/Sitzplatz Saal/Kinosaal Werbung Veranstaltung Eisverkauf Vorführung Kartenverkauf Ablaufplanung
  66. 26.09.23 //// Seite 546 WPS – Workplace Solutions REDUKTION AUF

    BOUNDED CONTEXT »KARTENVERKAUF« Saalplan Vorstellung Reservierungs- nummer Kinokarte Saalplanstapel Liste der Reservierungs- nummern Gesamtablauf- plan Tagesablaufplan Film Platz/Sitzplatz Saal/Kinosaal Werbung Veranstaltung Eisverkauf Vorführung Kartenverkauf Ablaufplanung
  67. 26.09.23 //// Seite 547 WPS – Workplace Solutions REDUKTION AUF

    BOUNDED CONTEXT »KARTENVERKAUF« Saalplan Vorstellung Reservierungs- nummer Kinokarte Saalplanstapel Liste der Reservierungs- nummern Film Platz/Sitzplatz Saal/Kinosaal
  68. 26.09.23 //// Seite 548 WPS – Workplace Solutions REDUKTION AUF

    BOUNDED CONTEXT »KARTENVERKAUF« Saalplan Vorstellung Reservierungs- nummer Kinokarte Saalplanstapel Liste der Reservierungs- nummern Film Platz/Sitzplatz Saal/Kinosaal
  69. 26.09.23 //// Seite 549 WPS – Workplace Solutions REDUKTION AUF

    BOUNDED CONTEXT »KARTENVERKAUF« Saalplan Vorstellung Reservierungs- nummer Kinokarte Saalplanstapel Liste der Reservierungs- nummern Film Platz/Sitzplatz Saal/Kinosaal
  70. 26.09.23 //// Seite 552 WPS – Workplace Solutions § Durch

    die Fachexperten (domain experts) § Sie wissen § Worum es bei ihrer Arbeit geht § Wo die Software sie unterstützen kann èWer die Fachlichkeit nicht versteht, kann ihr nicht helfen èSoftwareentwickler und Fachexperten bilden zusammen das Team WIE LERNEN WIR DIE FACHLICHKEIT? Foto: Brandon Raile/Wikipedia
  71. 26.09.23 //// Seite 553 WPS – Workplace Solutions WIE KOMMEN

    WIR AN DAS WISSEN DER FACHEXPERTEN? Techniken: § Interviews § Szenarios § Event Storming § Domain Storytelling Das wollen wir extrahieren! Foto: Brandon Raile/Wikipedia Fach- wissen
  72. 26.09.23 //// Seite 554 WPS – Workplace Solutions WORKSHOPS MIT

    ANWENDERN UND PRODUCT OWNERS “Georgia?” by The Library of Congress, flickr.com • Teilnehmer aus verschiedenen Bereichen (Business, IT, Management, …) • ein Moderator für den Workshop à direktes Feedback von allen Beteiligten
  73. 26.09.23 //// Seite 555 WPS – Workplace Solutions EVENT STORMING

    § Eine Methode um Geschäftsprozesse zu modellieren § Modelliert werden: § Domain Events § Commands § Akteure § Aggregates
  74. CUSTOMER TELLS WISH FOR 1 SALES-PERSON SIGNS TO GIVES FOR

    CONTRACT 3 RISIK MANAGER CONTRACT PASSES ON TO 4 CONTRACT VOTES CHECKS CALCULATES 5 6 7 CALCU- LATES TO 8 2 CAR CREDIT RATING INSTALLMENT CAR RESALE VALUE CONTRACT
  75. 26.09.23 //// Seite 560 WPS – Workplace Solutions FACHLICHE HANDLUNGEN

    IM KARTENVERKAUF Saalplan • Anzahl Plätze suchen • Verkaufte Plätze mark. • Reserv. Plätze mit RN markieren Vorstellung Reservierungs- nummer Kinokarte • Mit Platz beschriften Saalplanstapel • Saalplan zu Vorst. Holen • Saalplan zurücklegen Liste der Reservierungsnummern • Reservierungsnummer abholen • Name+Vorst. Vermerken • Vorst. Mit RN heraussuchen Film Platz/Sitzplatz Saal/Kinosaal
  76. 26.09.23 //// Seite 561 WPS – Workplace Solutions EINIGE DATEN

    ERGÄNZEN Vorstellung • Datum • Zeitraum • Film Kinokarte • Mit Platz beschriften • Vorstellung Film • Titel • Regisseur, Schauspieler • Freigabe • Spieldauer Platz/Sitzplatz • Reihe • Nummer Saal/Kinosaal • Kapazität • Anzahl Reihen Saalplan • Anzahl Plätze suchen • Verkaufte Plätze mark. • Reserv. Plätze mit RN markieren Reservierungs- nummer Saalplanstapel • Saalplan zu Vorst. Holen • Saalplan zurücklegen Liste der Reservierungsnummern • Reservierungsnummer abholen • Name+Vorst. Vermerken • Vorst. Mit RN heraussuchen
  77. 26.09.23 //// Seite 564 WPS – Workplace Solutions ARCHITECTURE WITH

    BOUNDED CONTEXTS TIDAL FORECAST MANEUVER PLANNING DEPTHS MEASUREMENT
  78. 26.09.23 //// Seite 565 WPS – Workplace Solutions ARCHITECTURE WITHIN

    A BOUNDED CONTEXT MANEUVER PLANNING User Interface Application Domain Infrastructure
  79. 26.09.23 //// Seite 566 WPS – Workplace Solutions DOMAIN-DRIVEN DESIGN—LAYER

    ARCHITECTURE § User interface layer § Receives input and user commands and presents information. § Application layer (Fowler: Service Layer) § Describes and coordinates application processes. § Domain layer § Represents the business domain logic. § Infrastructure layer § Provides technical services such as persistence or communication with other systems. User Interface Application Domain Infrastructure
  80. 26.09.23 //// Seite 567 WPS – Workplace Solutions LAYER ARCHITECTURE

    – CRITIQUE MANEUVER PLANNING § Domain layer is linked to the database layer § Technology “bubbles up” into domain layer § No clean separation of domain & technology Alistair Cockburn Foto: Fotograf Dennis Hamilton/Alistair Cockburn/flickr/CC BY 2.0 User Interface Application Domain Infrastructure
  81. 26.09.23 //// Seite 568 WPS – Workplace Solutions below above

    FROM ABOVE/BELOW TO INSIDE/OUTSIDE out- side inside
  82. 26.09.23 //// Seite 569 WPS – Workplace Solutions port port

    HEXAGONAL ARCHITECTURE Foto: Dennis Hamilton/flickr/CC BY 2.0 http://alistair.cockburn.us/Hexagonal%2Barchitecture adapter adapter Alistair Cockburn
  83. 26.09.23 //// Seite 570 WPS – Workplace Solutions KINDS OF

    PORTS - For UI etc. - Methods to be called - “from above” - For DB and infrastructure - Interfaces to be implemented - “from below”
  84. 26.09.23 //// Seite 571 WPS – Workplace Solutions ONION ARCHITECTURE

    U I “application core” domain services domain model infra app ture struc serv lication ices Jeffrey Palermo !
  85. 26.09.23 //// Seite 573 WPS – Workplace Solutions DIE OBJEKTORIENTIERTE

    GRUNDIDEE: FACHLICHE GEGENSTÄNDE ALS AUSGANGSPUNKT
  86. 26.09.23 //// Seite 574 WPS – Workplace Solutions FROM DOMAIN

    STORY TO DOMAIN MODEL Silhouette MOVES SILHOUETTE NAUTICAL OFFICER LENGTH Length moveBy(:Length) BY 8
  87. 26.09.23 //// Seite 576 WPS – Workplace Solutions En##es Value

    Objects Aggregates Services Factories Repositories
  88. 26.09.23 //// Seite 577 WPS – Workplace Solutions DOMAIN TERMS

    – WHAT IS STRIKING? insurance policy vacation request building activity purchase contract order zip code GPS coordinate IBAN container number IATA code
  89. 26.09.23 //// Seite 579 WPS – Workplace Solutions ENTITIES §

    Objects of a domain that the user works with. § The results of the work are reflected by their state! § Can be composed of other entities. § Have an (immutable) identity. § Maintain their own consistency and integrity! § Have a clearly defined life cycle. § Have a (mostly mutable) state. § Describe their state by value objects. § Synonyms: Business Object / Domain Object / Work Material § NOT TO BE confused with the term “ENTITY” from Entity-Relationship-Model! Foto: Bundesrepublik Deutschland/Wikipedia/PD Germany Foto: Kaz/pixabay/CC0 Foto: Thomas G./Wikipedia/CC BY-SA 3.0 Foto: OpenClipart-Vectors/pixabay/CC0
  90. 26.09.23 //// Seite 583 WPS – Workplace Solutions VALUE OBJECTS

    § Value objects are symbols for values of a certain type in the domain. § Symbolize the same value if they are equal. § They are not edited by the user and cannot be modified. § Can be calculated (from other value objects), if necessary. § Can consist of other value objects, but never of entities! ValueObject 2.5 ValueObject ValueObject ValueObject ValueObject two and a half
  91. 26.09.23 //// Seite 586 WPS – Workplace Solutions VALUE OBJECTS

    «Value Object» Depth centimeters : int equals()
  92. 26.09.23 //// Seite 590 WPS – Workplace Solutions ENTITIES UND

    VALUE OBJECTS IM KARTENVERKAUF Saalplan • Anzahl Plätze suchen • Verkaufte Plätze mark. • Reserv. Plätze mit RN markieren Vorstellung • Datum • Zeitraum • Film Reservierungs -nummer Kinokarte • Mit Platz beschriften • Vorstellung Saalplanstapel • Saalplan zu Vorst. Holen • Saalplan zurücklegen Liste der Reservierungsnummern • Reservierungsnummer abholen • Name+Vorst. Vermerken • Vorst. Mit RN heraussuchen Film • Titel • Regisseur, Schauspieler • Freigabe • Spieldauer Platz/Sitzplatz • Reihe • Nummer Saal/Kinosaal • Kapazität • Anzahl Reihen VO Entity Entity Entity Entity Entity Entity
  93. 26.09.23 //// Seite 591 WPS – Workplace Solutions ENTITIES UND

    VALUE OBJECTS IM KARTENVERKAUF Saalplan • Anzahl Plätze suchen • Verkaufte Plätze mark. • Reserv. Plätze mit RN markieren Vorstellung • Datum • Zeitraum • Film Reservierungs -nummer Liste der Reservierungsnummern • Reservierungsnummer abholen • Name+Vorst. Vermerken • Vorst. Mit RN heraussuchen Film • Titel • Regisseur, Schauspieler • Freigabe • Spieldauer Platz/Sitzplatz • Reihe • Nummer Saal/Kinosaal • Kapazität • Anzahl Reihen VO Entity Entity Entity Entity Entity Entity
  94. 26.09.23 //// Seite 593 WPS – Workplace Solutions REPOSITORIES §

    Are the access points to the aggregates! § Encapsulate the technical details of the technical infrastructure layer ... § ... and map external data to entities and value objects. § Store aggregates (e. g. in databases). Repository Aggregate Aggregate Aggregate Aggregate Aggregate
  95. 26.09.23 //// Seite 595 WPS – Workplace Solutions REPOSITORY: TWO

    PART IMPLEMENTATION «Repository Interface» DepthMapCabinet getDepthMap(Area, Scale) : DepthMap putBack(DepthMap) «Repository Implementation» MySQLDepthMapCabinet
  96. 26.09.23 //// Seite 596 WPS – Workplace Solutions AGGREGATES §

    Aggregates are entities that are relevant in themselves (and not just as part of another entity). § Protect the consistency and integrity of their inner entities. § They don't necessarily have to hide them to do this! § Always have a designated entity as an entry point (root). § Usually stored. § As a whole! § Not necessarily in a relational way! Root Entity VO VO VO Aggregate
  97. 26.09.23 //// Seite 597 WPS – Workplace Solutions AGGREGATES §

    Actually, the value objects are outside as they are immutable and may be reused anywhere. Root Entity VO VO VO Some other object Aggregate
  98. 26.09.23 //// Seite 598 WPS – Workplace Solutions AGGREGATES §

    An aggregate can consist of many entities. Root Entity Entity Entity Entity Entity VO VO VO VO VO VO VO VO VO VO VO Aggregate
  99. 26.09.23 //// Seite 600 WPS – Workplace Solutions Aggregate «Aggregate

    Root» DepthMap «Entity» Marking «Value Object» Depth
  100. 26.09.23 //// Seite 601 WPS – Workplace Solutions ENTITIES UND

    VALUE OBJECTS IM KARTENVERKAUF Saalplan • Anzahl Plätze suchen • Verkaufte Plätze mark. • Reserv. Plätze mit RN markieren Vorstellung • Datum • Zeitraum • Film Reservierungs -nummer Liste der Reservierungsnummern • Reservierungsnummer abholen • Name+Vorst. Vermerken • Vorst. Mit RN heraussuchen Film • Titel • Regisseur, Schauspieler • Freigabe • Spieldauer Platz/Sitzplatz • Reihe • Nummer Saal/Kinosaal • Kapazität • Anzahl Reihen VO Entity Entity Entity Entity Entity Entity
  101. 26.09.23 //// Seite 603 WPS – Workplace Solutions ENTITIES UND

    VALUE OBJECTS IM KARTENVERKAUF Saalplan • Anzahl Plätze suchen • Verkaufte Plätze mark. • Reserv. Plätze mit RN markieren Vorstellung • Datum • Zeitraum • Film Reservierungs -nummer Liste der Reservierungsnummern • Reservierungsnummer abholen • Name+Vorst. Vermerken • Vorst. Mit RN heraussuchen Film • Titel • Regisseur, Schauspieler • Freigabe • Spieldauer Platz/Sitzplatz • Reihe • Nummer Saal/Kinosaal • Kapazität • Anzahl Reihen VO Entity Entity Wurzel-Entity Entity Entity Entity Aggregate Aggregate Aggregate Aggregate Aggregate
  102. 26.09.23 //// Seite 623 WPS – Workplace Solutions A BANK

    ACCOUNT—FIRST DRAFT public class Account { }
  103. 26.09.23 //// Seite 624 WPS – Workplace Solutions A BANK

    ACCOUNT—FIRST DRAFT import org.jmolecules.ddd.annotation.Entity; @Entity public class Account { }
  104. 26.09.23 //// Seite 625 WPS – Workplace Solutions A BANK

    ACCOUNT—FIRST DRAFT import org.jmolecules.ddd.annotation.Entity; @Entity public class Account { }
  105. 26.09.23 //// Seite 626 WPS – Workplace Solutions A BANK

    ACCOUNT—FIRST DRAFT @Entity public class Account { private int _balance; public int getBalance() { return _balance; } public void setBalance(int balance) { _balance = balance; } } ✘ Bad: The account balance can be set to any value
  106. 26.09.23 //// Seite 627 WPS – Workplace Solutions A BANK

    ACCOUNT—SECOND VERSION @Entity public class Account { private int _balance; public int balance() { return _balance; } public void deposit(int amount) { _balance += amount; } public void withdraw(int amount) { _balance -= amount; } } Better: Operations with domain-specific behavior and names
  107. 26.09.23 //// Seite 628 WPS – Workplace Solutions A BANK

    ACCOUNT—THIRD VERSION @Entity public class Account { private int _balance; public int balance() { return _balance; } public void deposit(int amount) { _balance += amount; } public void withdraw(int amount) { if (amount > balance()) { throw new IllegalArgumentException("Amount too big"); } _balance -= amount; } Even better: Preconditions can be checked
  108. 26.09.23 //// Seite 630 WPS – Workplace Solutions DESIGN BY

    CONTRACT Foto: Urheber Fuchsias/Bertrand Meyer/Wikipedia/CC BY-SA 4.0
  109. 26.09.23 //// Seite 631 WPS – Workplace Solutions A BANK

    ACCOUNT—DESIGN BY CONTRACT USING “ASSERT” @Entity public class Account { // ... public void withdraw(int amount) { assert amount <= balance(); _balance -= amount; } } Assertion using keyword assert
  110. 26.09.23 //// Seite 632 WPS – Workplace Solutions A BANK

    ACCOUNT—DESIGN BY CONTRACT USING “VALID4J” import static org.valid4j.Assertive.*; @Entity public class Account { // ... public void withdraw(int amount) { require(amount <= balance()); _balance -= amount; } } Hamcrest matchers can be used
  111. 26.09.23 //// Seite 636 WPS – Workplace Solutions GREAT, BUT…

    @Entity public class Account { // ... public void withdraw(int amount) { assert amount <= balance(); _balance -= amount; } } Can I withdraw a negative amount? In EUR or GBP or…?
  112. 26.09.23 //// Seite 639 WPS – Workplace Solutions AN AMOUNT

    TYPE import org.jmolecules.ddd.annotation.ValueObject; @ValueObject public class Amount { }
  113. 26.09.23 //// Seite 640 WPS – Workplace Solutions AN AMOUNT

    TYPE @ValueObject public class Amount { private int _amount; private Currency _currency; }
  114. 26.09.23 //// Seite 641 WPS – Workplace Solutions AN AMOUNT

    TYPE @ValueObject public class Amount { private final int _amount; private final Currency _currency; }
  115. 26.09.23 //// Seite 642 WPS – Workplace Solutions AN AMOUNT

    TYPE @ValueObject public class Amount { private final int _amount; private final Currency _currency; public Amount(int amount, Currency currency) { _amount = amount; _currency = currency; } }
  116. 26.09.23 //// Seite 643 WPS – Workplace Solutions AN AMOUNT

    TYPE @ValueObject public class Amount { private final int _amount; private final Currency _currency; private Amount(int amount, Currency currency) { _amount = amount; _currency = currency; } public static Amount of(int amount, Currency currency) { return new Amount(amount, currency); } }
  117. 26.09.23 //// Seite 644 WPS – Workplace Solutions AN AMOUNT

    TYPE @ValueObject public class Amount { private final int _amount; private final Currency _currency; public Amount(int amount, Currency currency) { _amount = amount; _currency = currency; } @Override public boolean equals(Object other) { return _amount == ((Amount) other)._amount && _currency.equals(((Amount) other)._currency); } }
  118. 26.09.23 //// Seite 645 WPS – Workplace Solutions AN AMOUNT

    TYPE @ValueObject public class Amount { private final int _amount; private final Currency _currency; public Amount(int amount, Currency currency) { _amount = amount; _currency = currency; } @Override public boolean equals(Object other) { return _amount == ((Amount) other)._amount && _currency.equals(((Amount) other)._currency); } // hashCode() }
  119. 26.09.23 //// Seite 646 WPS – Workplace Solutions AN AMOUNT

    TYPE—JAVA 14 AND HIGHER @ValueObject public record Amount(int amount, Currency currency);
  120. 26.09.23 //// Seite 647 WPS – Workplace Solutions AN AMOUNT

    TYPE @ValueObject public class Amount { private final int _amount; private final Currency _currency; public Amount(int amount, Currency currency) { _amount = amount; _currency = currency; } public Amount add(Amount otherAmount) { return Amount.of(_amount + otherAmount._amount, _currency); } } The new value object type behaves correctly
  121. 26.09.23 //// Seite 648 WPS – Workplace Solutions AN AMOUNT

    TYPE @ValueObject public class Amount { private final int _amount; private final Currency _currency; public Amount(int amount, Currency currency) { _amount = amount; _currency = currency; } public Amount add(Amount otherAmount) { assert hasSameCurrency(otherAmount); return Amount.of(_amount + otherAmount._amount, _currency); } public boolean hasSameCurrency(Amount otherAmount) { return otherAmount._currency == _currency; ... and contracts ensure the correct currency
  122. 26.09.23 //// Seite 652 WPS – Workplace Solutions A BANK

    ACCOUNT—FOURTH VERSION @Entity public class Account { private Amount _balance; public Amount balance() { return _balance; } public void deposit(Amount amount) { _balance = _balance.add(amount); } public void withdraw(Amount amount) { assert amount.isLessOrEqual(balance()); _balance = _balance.subtract(amount); } } Now we can use the amount type
  123. 26.09.23 //// Seite 653 WPS – Workplace Solutions A BANK

    ACCOUNT—FOURTH VERSION @Entity public class Account { private Amount _balance; public Amount balance() { return _balance; } public void deposit(Amount amount) { _balance = _balance.add(amount); } public void withdraw(Amount amount) { assert amount.hasSameCurrency(balance()); assert amount.isLessOrEqual(balance()); _balance = _balance.subtract(amount); } } ... and define new contracts
  124. 26.09.23 //// Seite 654 WPS – Workplace Solutions A BANK

    ACCOUNT—EVENT SOURCED @Entity public class Account { private List<FinancialTransaction> _transactions; public Amount balance() { // sum up _transactions } public void deposit(Amount amount) { _transactions.append(new Deposition(amount)); } public void withdraw(Amount amount) { assert amount.hasSameCurrency(balance()); assert amount.isLessOrEqual(balance()); _transactions.append(new Withdrawal(amount)); } } History instead of current status
  125. 26.09.23 //// Seite 657 WPS – Workplace Solutions IDENTITY OF

    ENTITIES § In Java, every object has an identity § Namely its reference. § It's a technical identity. § An entity has a identity from a domain perspective § Different technical objects can represent the same entity § In different processes: e.g. on the client / on the server § When they are stored and later read from the database. § The identity can be implemented in two ways: § explicitly (e.g. IBAN) by using a unique key the user is aware of § implicitly (e.g. UUID / GUID) by using a technical key hidden from the user ?
  126. 26.09.23 //// Seite 658 WPS – Workplace Solutions A BANK

    ACCOUNT—WITH EXPLICIT IDENTITY @Entity public class Account { @Identity private final IBAN _iban; public Account(IBAN iban) { _iban = iban; } @Override public boolean equals(Object other) { return _iban.equals(((Account)other)._iban); } // ... } The identity is immutable The key is of course a value object The implementation of equals() is based on the identity
  127. 26.09.23 //// Seite 659 WPS – Workplace Solutions HOW CAN

    A NEW IDENTITY BE CREATED? § Database § Pro: Central § Can sometimes be created “lazily” § A system-wide value type factory § Domain-specific keys known to the user § Often implemented by the repository of a corresponding aggregate type the key is used for § A UUID / GUID generator § Pro: can be generated independently on any server or client § Con: String in a special format
  128. 26.09.23 //// Seite 660 WPS – Workplace Solutions BANK TRANSFER—BY

    DOMAIN SERVICE @Service public class CreditTransferService { public void transfer(Account source, Account destination, Amount amount) { source.withdraw(amount); destination.deposit(amount); } } No fields à stateless
  129. 26.09.23 //// Seite 663 WPS – Workplace Solutions EVERY BOUNDED

    CONTEXT HAS ITS OWN GLOSSARY—REVISITED DEPTH DEPTH AT A SPECIFIC GEO POSITION CONSIDERING THE CURRENT TIDAL LEVEL DEPTH DEPTH BELOW SEA LEVEL MEASURED BY ECHO SOUNDER MANEUVER PLANNING DEPTH MEASUREMENT
  130. 26.09.23 //// Seite 664 WPS – Workplace Solutions EVERY BOUNDED

    CONTEXT HAS ITS OWN IMPLEMENTATION public struct Depth { public Depth( int depthBelowSeaLevel, int tideLevel) { // ... } } MANEUVER PLANNING DEPTH MEASUREMENT public class Depth { public Depth( int centimeter, LocalDate soundingDate) { // ... } }
  131. 26.09.23 //// Seite 667 WPS – Workplace Solutions A BANK

    ACCOUNT—FIRST DRAFT public class Account { }
  132. 26.09.23 //// Seite 668 WPS – Workplace Solutions A BANK

    ACCOUNT—FIRST DRAFT using NMolecules.DDD; [Entity] public class Account { }
  133. 26.09.23 //// Seite 669 WPS – Workplace Solutions A BANK

    ACCOUNT—FIRST DRAFT [Entity] public class Account { public int Balance { get; set; } } ✘ Bad: The account balance can be set to any value
  134. 26.09.23 //// Seite 670 WPS – Workplace Solutions A BANK

    ACCOUNT—SECOND VERSION [Entity] public class Account { public int Balance { get; private set; } public void Deposit(int amount) { Balance += amount; } public void Withdraw(int amount) { Balance -= amount; } } Better: Operations with domain-specific behavior and names
  135. 26.09.23 //// Seite 671 WPS – Workplace Solutions A BANK

    ACCOUNT—THIRD VERSION [Entity] public class Account { public int Balance { get; private set; } public void Deposit(int amount) { Balance += amount; } public void Withdraw(int amount) { if (amount > balance()) { throw new ArgumentException("Amount too big"); } Balance -= amount; } Even better: Preconditions can be checked
  136. 26.09.23 //// Seite 673 WPS – Workplace Solutions DESIGN BY

    CONTRACT Foto: Urheber Fuchsias/Bertrand Meyer/Wikipedia/CC BY-SA 4.0
  137. 26.09.23 //// Seite 674 WPS – Workplace Solutions A BANK

    ACCOUNT—DESIGN BY CONTRACT USING “ASSERT” using static System.Diagnostics.Debug; [Entity] public class Account { // ... public void Withdraw(int amount) { Assert(amount <= balance()); Balance -= amount; } } Assertion using Debug.Assert
  138. 26.09.23 //// Seite 677 WPS – Workplace Solutions GREAT, BUT…

    using static System.Diagnostics.Debug; [Entity] public class Account { // ... public void Withdraw(int amount) { Assert(amount <= balance()); Balance -= amount; } } Can I withdraw a negative amount? In EUR or GBP or…?
  139. 26.09.23 //// Seite 680 WPS – Workplace Solutions AN AMOUNT

    TYPE using NMolecules.DDD; [ValueObject] public class Amount { }
  140. 26.09.23 //// Seite 681 WPS – Workplace Solutions AN AMOUNT

    TYPE [ValueObject] public class Amount { private int _amount; private Currency _currency; }
  141. 26.09.23 //// Seite 682 WPS – Workplace Solutions AN AMOUNT

    TYPE [ValueObject] public class Amount { private readonly int _amount; private readonly Currency _currency; }
  142. 26.09.23 //// Seite 683 WPS – Workplace Solutions AN AMOUNT

    TYPE [ValueObject] public class Amount { private readonly int _amount; private readonly Currency _currency; public Amount(int amount, Currency currency) { _amount = amount; _currency = currency; } }
  143. 26.09.23 //// Seite 684 WPS – Workplace Solutions AN AMOUNT

    TYPE [ValueObject] public class Amount { private readonly int _amount; private readonly Currency _currency; private Amount(int amount, Currency currency) { _amount = amount; _currency = currency; } public static Amount Of(int amount, Currency currency) { return new Amount(amount, currency); } }
  144. 26.09.23 //// Seite 685 WPS – Workplace Solutions AN AMOUNT

    TYPE [ValueObject] public class Amount { private readonly int _amount; private readonly Currency _currency; // ... public override bool Equals(object other) { return other is Amount && _amount == ((Amount) other)._amount && _currency.Equals(((Amount) other)._currency); } }
  145. 26.09.23 //// Seite 686 WPS – Workplace Solutions AN AMOUNT

    TYPE [ValueObject] public class Amount { private readonly int _amount; private readonly Currency _currency; // ... public override bool Equals(object other) => other is Amount && _amount == ((Amount) other)._amount && _currency.Equals(((Amount) other)._currency); }
  146. 26.09.23 //// Seite 687 WPS – Workplace Solutions AN AMOUNT

    TYPE [ValueObject] public class Amount { private readonly int _amount; private readonly Currency _currency; // ... public override bool Equals(object other) => other is Amount && _amount == ((Amount) other)._amount && _currency.Equals(((Amount) other)._currency); // GetHashCode() }
  147. 26.09.23 //// Seite 688 WPS – Workplace Solutions AN AMOUNT

    TYPE [ValueObject] public class Amount { private readonly int _amount; private readonly Currency _currency; // ... public static bool operator ==(Amount a, Amount b) => a.Equals(b); }
  148. 26.09.23 //// Seite 689 WPS – Workplace Solutions AN AMOUNT

    TYPE [ValueObject] public class Amount { private readonly int _amount; private readonly Currency _currency; // ... public static bool operator ==(Amount a, SignDate b) => a.Equals(b); public static bool operator !=(Amount a, SignDate b) => !a.Equals(b); }
  149. 26.09.23 //// Seite 693 WPS – Workplace Solutions AN AMOUNT

    TYPE [ValueObject] public struct Amount { private readonly int _amount; private readonly Currency _currency; public Amount(int amount, Currency currency) { _amount = amount; _currency = currency; } }
  150. 26.09.23 //// Seite 694 WPS – Workplace Solutions AN AMOUNT

    TYPE [ValueObject] public struct Amount { private readonly int _amount; private readonly Currency _currency; public Amount(int amount, Currency currency) { _amount = amount; _currency = currency; } // Equals() does not have to be overridden }
  151. 26.09.23 //// Seite 695 WPS – Workplace Solutions AN AMOUNT

    TYPE [ValueObject] public struct Amount { private readonly int _amount; private readonly Currency _currency; public Amount(int amount, Currency currency) { _amount = amount; _currency = currency; } // but the operators have to be overridden }
  152. 26.09.23 //// Seite 697 WPS – Workplace Solutions AN AMOUNT

    TYPE—C# 9 AND HIGHER [ValueObject] public record Amount(int amount, Currency currency);
  153. 26.09.23 //// Seite 698 WPS – Workplace Solutions AN AMOUNT

    TYPE—C# 9 AND HIGHER [ValueObject] public record Amount(int amount, Currency currency); // automatically readonly // Equals(), GetHashCode(), ToString(), operators // do not have to be overloaded and work as expected
  154. 26.09.23 //// Seite 699 WPS – Workplace Solutions AN AMOUNT

    TYPE—C# 9 AND HIGHER [ValueObject] public record struct Amount(int amount, Currency currency);
  155. 26.09.23 //// Seite 700 WPS – Workplace Solutions AN AMOUNT

    TYPE—C# 10 AND HIGHER [ValueObject] public readonly record struct Amount(int amount, Currency currency);
  156. 26.09.23 //// Seite 701 WPS – Workplace Solutions AN AMOUNT

    TYPE [ValueObject] public readonly record struct Amount(int _amount, Currency _currency) { public Amount Add(Amount otherAmount) { return Amount.of(_amount + otherAmount._amount, _currency); } } The new value object type behaves correctly
  157. 26.09.23 //// Seite 702 WPS – Workplace Solutions AN AMOUNT

    TYPE [ValueObject] public readonly record struct Amount(int amount, Currency currency) { public Amount Add(Amount otherAmount) { Assert(HasSameCurrency(otherAmount)); return Amount.of(_amount + otherAmount.amount, currency); } public boolean HasSameCurrency(Amount otherAmount) => otherAmount.currency == currency; } ... and contracts ensure the correct currency
  158. 26.09.23 //// Seite 703 WPS – Workplace Solutions AN AMOUNT

    TYPE [ValueObject] public readonly record struct Amount(int amount, Currency currency) { public Amount operator +(Amount otherAmount) { Assert(HasSameCurrency(otherAmount)); return Amount.Of(_amount + otherAmount._amount, _currency); } public boolean HasSameCurrency(Amount otherAmount) { return otherAmount._currency == _currency; } }
  159. 26.09.23 //// Seite 704 WPS – Workplace Solutions A BANK

    ACCOUNT—FOURTH VERSION [Entity] public class Account { public Amount Balance { get; private set; } public void Deposit(Amount amount) { Balance += amount; } public void Withdraw(Amount amount) { Assert(amount <= Balance); Balance -= amount; } } Now we can use the amount type
  160. 26.09.23 //// Seite 705 WPS – Workplace Solutions A BANK

    ACCOUNT—FOURTH VERSION [Entity] public class Account { public Amount Balance { get; private set; } public void Deposit(Amount amount) { Balance += amount; } public void Withdraw(Amount amount) { Assert(amount.HasSameCurrencyAs(Balance); Assert(amount <= Balance); Balance -= amount; } } ... and define new contracts
  161. 26.09.23 //// Seite 706 WPS – Workplace Solutions A BANK

    ACCOUNT—EVENT SOURCED @Entity public class Account { private List<FinancialTransaction> _transactions; public Amount balance() { // sum up _transactions } public void deposit(Amount amount) { _transactions.append(new Deposition(amount)); } public void withdraw(Amount amount) { assert amount.hasSameCurrency(balance()); assert amount.isLessOrEqual(balance()); _transactions.append(new Withdrawal(amount)); } } History instead of current status
  162. 26.09.23 //// Seite 709 WPS – Workplace Solutions IDENTITY OF

    ENTITIES § In Java, every object has an identity § Namely its reference. § It's a technical identity. § An entity has a identity from a domain perspective § Different technical objects can represent the same entity § In different processes: e.g. on the client / on the server § When they are stored and later read from the database. § The identity can be implemented in two ways: § explicitly (e.g. IBAN) by using a unique key the user is aware of § implicitly (e.g. UUID / GUID) by using a technical key hidden from the user ?
  163. 26.09.23 //// Seite 710 WPS – Workplace Solutions A BANK

    ACCOUNT—WITH EXPLICIT IDENTITY @Entity public class Account { @Identity private final IBAN _iban; public Account(IBAN iban) { _iban = iban; } @Override public boolean equals(Object other) { return _iban.equals(((Account)other)._iban); } // ... } The identity is immutable The key is of course a value object The implementation of equals() is based on the identity
  164. 26.09.23 //// Seite 711 WPS – Workplace Solutions HOW CAN

    A NEW IDENTITY BE CREATED? § Database § Pro: Central § Can sometimes be created “lazily” § A system-wide value type factory § Domain-specific keys known to the user § Often implemented by the repository of a corresponding aggregate type the key is used for § A UUID / GUID generator § Pro: can be generated independently on any server or client § Con: String in a special format
  165. 26.09.23 //// Seite 712 WPS – Workplace Solutions BANK TRANSFER—BY

    DOMAIN SERVICE @Service public class CreditTransferService { public void transfer(Account source, Account destination, Amount amount) { source.withdraw(amount); destination.deposit(amount); } } No fields à stateless
  166. 26.09.23 //// Seite 715 WPS – Workplace Solutions EVERY BOUNDED

    CONTEXT HAS ITS OWN GLOSSARY—REVISITED DEPTH DEPTH AT A SPECIFIC GEO POSITION CONSIDERING THE CURRENT TIDAL LEVEL DEPTH DEPTH BELOW SEA LEVEL MEASURED BY ECHO SOUNDER MANEUVER PLANNING DEPTH MEASUREMENT
  167. 26.09.23 //// Seite 716 WPS – Workplace Solutions EVERY BOUNDED

    CONTEXT HAS ITS OWN IMPLEMENTATION public struct Depth { public Depth( int depthBelowSeaLevel, int tideLevel) { // ... } } MANEUVER PLANNING DEPTH MEASUREMENT public class Depth { public Depth( int centimeter, LocalDate soundingDate) { // ... } }
  168. 26.09.23 //// Seite 719 WPS – Workplace Solutions A BANK

    ACCOUNT—FIRST DRAFT class Account { }
  169. 26.09.23 //// Seite 720 WPS – Workplace Solutions A BANK

    ACCOUNT—FIRST DRAFT use PHPMolecules\DDD\Attribute\Entity; #[Entity] class Account { }
  170. 26.09.23 //// Seite 721 WPS – Workplace Solutions A BANK

    ACCOUNT—FIRST DRAFT #[Entity] class Account { private int $balance; public function getBalance(): int { return $this->balance; } public function setBalance(int $balance): void { $this-> balance = $balance; } } ✘ Bad: The account balance can be set to any value
  171. 26.09.23 //// Seite 722 WPS – Workplace Solutions A BANK

    ACCOUNT—SECOND VERSION #[Entity] class Account { private int $balance; public funtion balance(): int { return $this->balance; } public function deposit(int amount): void { $this->balance += amount; } public function withdraw(int amount): void { $this->balance -= amount; } } Better: Operations with domain-specific behavior and names
  172. 26.09.23 //// Seite 723 WPS – Workplace Solutions A BANK

    ACCOUNT—THIRD VERSION Even better: Preconditions can be checked #[Entity] class Account { private int $balance; public funtion balance(): int { return $this->balance; } public function deposit(int amount): void { $this->balance += amount; } public function withdraw(int amount): void { assert(amount <= $this->balance()); $this->balance -= amount; }
  173. 26.09.23 //// Seite 725 WPS – Workplace Solutions DESIGN BY

    CONTRACT Foto: Urheber Fuchsias/Bertrand Meyer/Wikipedia/CC BY-SA 4.0
  174. 26.09.23 //// Seite 726 WPS – Workplace Solutions DESIGN BY

    CONTRACT IN PHP § https://github.com/php-deal § http://www.terminally-incoherent.com/blog/2008/06/05/design-by-contract-in-php-with-assertions/
  175. 26.09.23 //// Seite 727 WPS – Workplace Solutions GREAT, BUT…

    #[Entity] class Account { // ... public function withdraw(int $amount): void { assert($amount <= $this->balance()); $this->balance -= $amount; } } Can I withdraw a negative amount? In EUR or GBP or…?
  176. 26.09.23 //// Seite 730 WPS – Workplace Solutions AN AMOUNT

    TYPE use PHPMolecules\DDD\Attribute\ValueObject; #[ValueObject] class Amount { }
  177. 26.09.23 //// Seite 731 WPS – Workplace Solutions AN AMOUNT

    TYPE #[ValueObject] class Amount { private int $amount; private Currency $currency; }
  178. 26.09.23 //// Seite 732 WPS – Workplace Solutions AN AMOUNT

    TYPE #[ValueObject] class Amount { private readonly int $amount; private readonly Currency $currency; }
  179. 26.09.23 //// Seite 734 WPS – Workplace Solutions AN AMOUNT

    TYPE #[ValueObject] class Amount { private readonly int $amount; private readonly Currency $currency; public function __construct(int $amount, Currency $currency) { $this->amount = $amount; $this->currency = $currency; } }
  180. 26.09.23 //// Seite 735 WPS – Workplace Solutions AN AMOUNT

    TYPE—PHP 8.1 AND HIGHER #[ValueObject] class Amount { public function __construct( private readonly int $amount, private readonly Currency $currency ) {} }
  181. 26.09.23 //// Seite 736 WPS – Workplace Solutions AN AMOUNT

    TYPE—PHP 8.2 AND HIGHER #[ValueObject] readonly class Amount { public function __construct( private int $amount; private Currency $currency; ) {} }
  182. 26.09.23 //// Seite 737 WPS – Workplace Solutions AN AMOUNT

    TYPE #[ValueObject] readonly class Amount { private function __construct( private int $amount, private Currency $currency ) {} public static function of(int $amount, Currency $currency): Amount { return new Amount($amount, $currency); } }
  183. 26.09.23 //// Seite 738 WPS – Workplace Solutions AN AMOUNT

    TYPE #[ValueObject] readonly class Amount { public function __construct( private int $amount; private Currency $currency; ) {} public function equals(Amount $other): bool { return $this->amount === $other->amount && $this->currency->equals($other->currency); } }
  184. 26.09.23 //// Seite 741 WPS – Workplace Solutions AN AMOUNT

    TYPE #[ValueObject] readonly class Amount { public function __construct( private int $amount, private Currency $currency ) {} public function add(Amount $otherAmount): Amount { return Amount.of($this->amount + $otherAmount->amount, $this->currency); } } The new value object type behaves correctly
  185. 26.09.23 //// Seite 742 WPS – Workplace Solutions AN AMOUNT

    TYPE #[ValueObject] readonly class Amount { public function __construct( private int $amount, private Currency $currency ) {} public function add(Amount $otherAmount): Amount { assert($this->hasSameCurrencyAs($otherAmount)); return Amount.of($this->amount + $otherAmount->amount, $this->currency); } public function hasSameCurrencyAs(Amount $otherAmount): bool { return $this->currency === $otherAmount->currency; } } ... and contracts ensure the correct currency
  186. 26.09.23 //// Seite 743 WPS – Workplace Solutions A BANK

    ACCOUNT—FOURTH VERSION Now we can use the amount type #[Entity] class Account { private Amount $balance; public function balance(): Amount { return $this->balance; } public function deposit(Amount $amount): void { $this->balance = $this->balance->add($amount); } public function withdraw(Amount $amount): void { assert($amount.isLessOrEqual($this->balance()); $this->balance = $this->balance->subtract($amount); }
  187. 26.09.23 //// Seite 744 WPS – Workplace Solutions #[Entity] class

    Account { private Amount $balance; public function balance(): Amount { return $this->balance; } public function deposit(Amount $amount): void { $this->balance = $this->balance->add($amount); } public function withdraw(Amount $amount): void { assert $amount.hasSameCurrency($this->balance()); assert($amount.isLessOrEqual($this->balance()); $this->balance = $this->balance->subtract($amount); A BANK ACCOUNT—FOURTH VERSION ... and define new contracts
  188. 26.09.23 //// Seite 745 WPS – Workplace Solutions A BANK

    ACCOUNT—EVENT SOURCED @Entity public class Account { private List<FinancialTransaction> _transactions; public Amount balance() { // _transactions aufsummieren } public void deposit(Amount amount) { _transactions.append(new Deposition(amount)); } public void withdraw(Amount amount) { assert amount.hasSameCurrency(balance()); assert amount.isLessOrEqual(balance()); _transactions.append(new Withdrawal(amount)); } } History instead of current status
  189. 26.09.23 //// Seite 748 WPS – Workplace Solutions IDENTITY OF

    ENTITIES § In Java, every object has an identity § Namely its reference. § It's a technical identity. § An entity has a identity from a domain perspective § Different technical objects can represent the same entity § In different processes: e.g. on the client / on the server § When they are stored and later read from the database. § The identity can be implemented in two ways: § explicitly (e.g. IBAN) by using a unique key the user is aware of § implicitly (e.g. UUID / GUID) by using a technical key hidden from the user ?
  190. 26.09.23 //// Seite 749 WPS – Workplace Solutions A BANK

    ACCOUNT—USING A UNIQUE KEY @Entity public class Account { @Identity private final IBAN _iban; public Account(IBAN iban) { _iban = iban; } @Override public boolean equals(Object other) { return _iban.equals(((Account)other)._iban); } // ... } The identity is immutable The key is of course a value object The implementation of equals () is based on the unique key
  191. 26.09.23 //// Seite 750 WPS – Workplace Solutions HOW CAN

    A NEW UNIQUE KEY BE CREATED? § Database § Pro: Central § Can sometimes be created “lazily” § A system-wide value type factory § Domain-specific keys known to the user § Often implemented by the repository of a corresponding aggregate type the key is used for § A UUID / GUID generator § Pro: can be generated independently on any server or client § Con: String in a special format
  192. 26.09.23 //// Seite 751 WPS – Workplace Solutions BANK TRANSFER—BY

    DOMAIN SERVICE @Service public class CreditTransferService { public void transfer(Account source, account destination, Amount amount) { source.withdraw(amount); destination.deposit(amount); } } No fields à stateless
  193. 26.09.23 //// Seite 754 WPS – Workplace Solutions EVERY BOUNDED

    CONTEXT HAS ITS OWN GLOSSARY—REVISITED DEPTH DEPTH AT A SPECIFIC GEO POSITION CONSIDERING THE CURRENT TIDAL LEVEL DEPTH DEPTH BELOW SEA LEVEL MEASURED BY ECHO SOUNDER MANEUVER- PLANNING SOUNDING SERVICE
  194. 26.09.23 //// Seite 755 WPS – Workplace Solutions EVERY BOUNDED

    CONTEXT HAS ITS OWN IMPLEMENTATION public struct Depth { public Depth( int depthBelowSeaLevel, int tideLevel) { // ... } } MANEUVER- PLANNING SOUNDING SERVICE public class Depth { public Depth( int centimeter, LocalDate soundingDate) { // ... } }
  195. Conways Law Blue Book Red Book 2015 ’16 ’17 ’14

    ’13 ’12 2010 ’11 ’09 ’08 ’07 ’06 2005 ’04 ’03 ’02 2000 01 1968 ... ’99 ’98 ’19 2020 ’18
  196. @hschwentner Bibliography Brandolini, Alberto. Introducing EventStorming. Self-published, Leanpub. Cockburn, Alistair.

    “Hexagonal Architecture.” January 4, 2005. https://alistair.cockburn.us/hexagonal-architecture/. Conway, Melvin E. “How Do Committees Invent?” Datamation 14, no. 5 (April 1968): 28–31. Evans, Eric. Domain-Driven Design: Tackling Complexity in the Heart of Software. Boston: Addison-Wesley, 2004. Foote, Brian and Joseph Yoder. “Big Ball of Mud.” PLoP ’97, Monticello, IL, September 1997. Fowler, Martin. Patterns of Enterprise Application Architecture. Boston: Addison- Wesley, 2003. Fowler, Martin. “Strangler Fig Application.” Bliki, June 29, 2004. Hofer, Stefan and Henning Schwentner. Domain Storytelling: a Collaborative, Visual, and Agile Way to Develop Domain-Driven Software. Boston: Addison-Wesley, 2022.