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

Vom Big Ball of Mud zu DDD – Der Weg zu einem w...

Vom Big Ball of Mud zu DDD – Der Weg zu einem wohl-strukturierten Monolithen

Domain-driven Design ist als Ansatz zur Modellierung von komplexer Software aus der modernen Software-Architektur nicht mehr wegzudenken. Bei der Konzeption neuer Software-Projekte hilft DDD mit einer ubiquitären Sprache das Verständnis für die anstehenden Herausforderungen zu erkennen und zu lösen.

Aber was ist mit bereits vorhandenen Software-Produkten? Auch schlecht strukturierte Legacy-Software ("Big Ball of Mud") kann mit der Einführung von DDD wieder in einen wartungsfähigen Zustand gebracht werden.

Dieser Vortrag beantwortet, anhand von Praxis-Erfahrungen aus Projekten in denen nachträglich DDD eingeführt wurde, folgende Fragen:

* Welche Vorteile bringt DDD überhaupt im Kontext von Legacy-Software?
* Bringt es auch Vorteile in einem Monolithen?
* Wie erreicht man einen Zustand, aus dem heraus eine Umstrukturierung überhaupt möglich ist?
* Wie können Domänen identifiziert werden?
* Wie kann Kompatibilität in der Übergangsphase gewährleistet werden?

Christian Nockemann

September 26, 2019
Tweet

More Decks by Christian Nockemann

Other Decks in Programming

Transcript

  1. VOM BIG BALL OF MUD ZU DDD Der Weg zu

    einem wohl-strukturierten Monolithen
  2. 26.09.2019 © viadee 2018 2 Christian Nockemann Senior Berater (bei

    der viadee seit 2009) Kernthemen: Software-Architektur, Enterprise Java Email: [email protected] Twitter: @nockemannc
  3. BIG BALL OF MUD WAS FÜR PROBLEME BRINGT ER MIT

    SICH? Zirkuläre Abhängigkeiten Langsame Builds und schlechte Skalierbarkeit Fragile Software
  4. WAS WOLLEN WIR? UND WARUM? 10 26.09.2019 © viadee 2018

    Unabhängige und cross-funktionale Teams Robustheit und Änderbarkeit Agilität
  5. Sicherung des Betriebs !!! Atomare Schritte Integrations- tests Rückwärts- kompatibilität

    NOTWENDIGE BEDINGUNG GRUNDVORAUSSETZUNG FÜR EINEN ERFOLG 15 26.09.2019 © viadee 2018
  6. API / Impl Onion Archi- tecture Strangler Pattern Getrennte Domänen

    Neuer Techno- logie Stack Shared Kernel Extraktion des Domänen- modells Separation of Concerns WAS IST ZU TUN? ÜBERGREIFENDE AUFGABENPAKETE 16 26.09.2019 © viadee 2018
  7. 21 26.09.2019 © viadee 2018 • de.xyz • domain •

    KundeAggregat • kundendaten • AdresseVO • KundeVO • application • KundeAggregatDtoMapper • KundeRepositoryInterface • dto • KundeDTO • KundeAppService • infrastructure • persistence • KundeRepository • entity • Kunde ONION ARCHITECTURE BEISPIEL PACKAGE-STRUKTUR
  8. 24 26.09.2019 © viadee 2018 AUFTEILUNG IN API UND IMPL

    ABHÄNGIGKEITEN ENTWIRREN A B Impl Impl API API runtime
  9. Ausgangszustand Alte Laufzeitumgebung 28 26.09.2019 © viadee 2018 STRANGLER PATTERN

    SCHRITTWEISE MIGRATION A B C Repo Schritt 1 Alte Laufzeitumgebung A B C Repo RMI RMI Neue Laufzeitumgebung C* REST RMI RMI RMI REST API API API API
  10. Ausgangszustand Alte Laufzeitumgebung 29 26.09.2019 © viadee 2018 STRANGLER PATTERN

    SCHRITTWEISE MIGRATION A B C Repo Schritt 2 Alte Laufzeitumgebung A B C Repo RMI RMI Neue Laufzeitumgebung C* RMI RMI RMI REST B* REST API API API API
  11. Ausgangszustand Alte Laufzeitumgebung 30 26.09.2019 © viadee 2018 STRANGLER PATTERN

    SCHRITTWEISE MIGRATION A B C Repo Schritt 2 Alte Laufzeitumgebung A B C Repo RMI RMI Neue Laufzeitumgebung C* RMI RMI RMI REST B* REST Repo* API API API API A* REST
  12. 31 26.09.2019 © viadee 2018 STRANGLER PATTERN SCHRITTWEISE MIGRATION Lauffähig

    in alter Laufzeitumgebung API Controller RMI Domain POJO Delegation Lauffähig in neuer Laufzeitumgebung Controller REST Delegation
  13. DIE „ALTE“ KENNT DIE „NEUE“ WELT ABER NICHT UMGEKEHRT! 33

    26.09.2019 © viadee 2018 Neue Laufzeitumgebung Core C D Alte Laufzeitumgebung A B
  14. WIE GEHABT: API! WICHTIG: FREI VON DRITT-ABHÄNGIGKEITEN! 34 26.09.2019 ©

    viadee 2018 Neue Laufzeitumgebung (Java 11+) C D Alte Laufzeitumgebung (Java 6) A B API (Java 6 compliant) Core API *Java 6 compliant Gift- schrank*
  15. 36 26.09.2019 © viadee 2018 FALLSTRICKE LERNEN AUS SCHMERZEN Transaktionen

    CI- Konfiguration Jahres- arbeiten Exception Handling Laufzeit der Integrations- tests
  16. EINE DOMÄNE IM ÜBERBLICK DAS ENDERGEBNIS 37 26.09.2019 © viadee

    2018 Domäne A Kern Repository API REST Controller JMS Listener HTTP Queue UI ACL Adapter B Adapter C Srv B Srv C Domäne B HTTP Domäne C Queue
  17. EXTRAKTION DES DOMÄNENMODELLS ENTITIES, VALUE-OBJECTS, AGGREGATES 38 26.09.2019 © viadee

    2018 public class LegacyInkassoService { public void inkasso(String vorname, String nachname, double betrag, String emailAdresse, String iban){ String betreff = "..."; String inhalt = "..."; String.format(inhalt, vorname, nachname); mailService.sende(emailAdresse, betreff, inhalt); String bic = ermittleBic(iban); lastschriftService.uebermittleLastschrift(iban, bic, betrag); // ... } // ...
  18. EXTRAKTION DES DOMÄNENMODELLS ENTITIES, VALUE-OBJECTS, AGGREGATES 39 26.09.2019 © viadee

    2018 public class Email { public Email(String vorname, String nachname, String mailAdresse) { this.vorname = vorname; this.nachname = nachname; this.mailAdresse = mailAdresse; this.betreff = "..."; this.inhalt = "..."; String.format(inhalt, vorname, nachname); } // ... }
  19. EXTRAKTION DES DOMÄNENMODELLS ENTITIES, VALUE-OBJECTS, AGGREGATES 40 26.09.2019 © viadee

    2018 @ValueObject public class Email { public Email(Person person, String mailAdresse) { this.mailAdresse = mailAdresse; this.betreff = "..."; this.inhalt = "..."; String.format(inhalt, person.vorname(), person.nachname()); } // ... }
  20. EXTRAKTION DES DOMÄNENMODELLS ENTITIES, VALUE-OBJECTS, AGGREGATES 41 26.09.2019 © viadee

    2018 @ValueObject public class Email { public static Email erstelle(Person person){ Validate.validateNotNull(person); verifiziereMailAdresse(person.mailAdresse()); return new Email(person, person.mailAdresse()); } // ... }
  21. EXTRAKTION DES DOMÄNENMODELLS ENTITIES, VALUE-OBJECTS, AGGREGATES 42 26.09.2019 © viadee

    2018 @Aggregate public class InkassoVorgang { private final InkassoVorgangId id; private final Iban iban; private final Person person; private final Betrag betrag; private final Email email; // ... }
  22. EXTRAKTION DES DOMÄNENMODELLS ENTITIES, VALUE-OBJECTS, AGGREGATES 43 26.09.2019 © viadee

    2018 @Aggregate public class InkassoVorgang { static InkassoVorgang erstelle(InkassoVorgangId id, Person person, Betrag betrag){ return new InkassoVorgang(id, person, person.iban(), betrag Email.erstelle(inkassoVorgang.person())); } public KreditInstitut ermittleKreditinstitut(){ return KreditInstitut.erstelleKreditInstitut(this.iban); } // ... }
  23. EXTRAKTION DES DOMÄNENMODELLS ENTITIES, VALUE-OBJECTS, AGGREGATES 44 26.09.2019 © viadee

    2018 @ApplicationService public class InkassoService { public void inkasso(InkassoVorgang inkassoVorgang){ Validate.validateNotNull(inkassoVorgang); validiereBetrag(inkassoVorgang.betrag()); mailService.sende(inkassovorgang.email()); lastschriftService.uebermittleLastschrift( inkassoVorgang.iban(), inkassoVorgang.ermittleKreditinstitut(), inkassoVorgang.betrag()); inkassoRepository.persist(inkassoVorgang); } // ...