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

Objektorientierung, Domain-Driven Design und Architectur

Objektorientierung, Domain-Driven Design und Architectur

My talk(German) I gave about DDD and software architecture.

Mirko Sertic

March 03, 2013
Tweet

More Decks by Mirko Sertic

Other Decks in Programming

Transcript

  1. Objektorientierung, Domain-driven
    Design und Architektur
    Mirko Sertic
    [email protected]

    View Slide

  2. Agenda
    Seite 2
    • Ein paar Worte zu Projekten
    • Das Wesen von Software
    • Bausteine Domain-driven Design
    • Schichtenarchitektur mal anders
    • Messaging und WebServices
    • Weiterführende Themen
    • Diskussion

    View Slide

  3. Ein paar Worte zu Projekten
    Das typische Projekt
    Seite 3
    Der Turmbau zu Babel

    View Slide

  4. Ein paar Worte zu Projekten
    Warum sind die Babylonier gescheitert?
    Seite 4
    • Ein MONSTRÖSES Projekt
    • Sie wollten zu viel auf einmal
    • Sie haben sich mit höheren Mächten angelegt
    • Dafür wurden sie mit Sprachverwirrung bestraft
    • Die Projektbeteiligten haben sich nicht mehr verstanden
    • Zum Schluss gingen alle getrennte Wege
    • Übrig blieb eine Ruine

    View Slide

  5. Ein paar Worte zu Projekten
    Die Welt der Informatik
    Seite 5
    • Wir haben grosse Projekte
    • Wir haben ehrgeizige Ziele
    • Wir haben wenig Zeit
    • Manchmal auch Sprachverwirrung
    • Verstehen wir unsere Kunden wirklich?
    • Niemand will eine Ruine
    Und das alles gibt es gratis ohne biblischen Fluch ;-)

    View Slide

  6. Das Wesen von Software
    Fangen wir mit Software an
    Seite 6
    • Software ist immateriell
    • Sie besteht aus den Sprachen und Notationen, in denen
    sie formuliert ist
    • Software ist auch ein Modell
    • Ein Modell ist die Abbildung eines Realitätsausschnitts
    • Modell = Struktur + Verhalten
    • Das Modell definiert die Umsetzung der Anforderungen
    unserer Stakeholder

    View Slide

  7. Das Wesen von Software
    Mit Modellen ist das so eine Sache
    Seite 7
    Der Informatiker(Wir) Der Kunde(Vertrieb)
    Welches Framework? Der Webshop muss gut
    Welche Programmiersprache? aussehen
    Es geht um einen Webshop…
    Der Kunde(Finanzbuchhaltung)
    Ich brauche eine Statistik über
    Quartalszahlen
    Modell

    View Slide

  8. Das Wesen von Software
    Warum brauchen wir ein Modell
    Seite 8
    • Wir brauchen einen Überblick
    • Wir brauchen eine Diskussionsgrundlage
    • Wir müssen Zusammenhänge verstehen
    • Wir brauchen einen (Bau)Plan unserer Software

    View Slide

  9. Das Wesen von Software
    Wie funktioniert Modellbildung?
    Seite 9
    • Abgrenzung
    • Nichtberücksichtigung irrelevanter Objekte
    • Dekomposition
    • Zerlegung und Auflösung in einzelne
    Segmente(Teilmodelle)
    • Reduktion
    • Weglassen von Objektdetails
    • Aggregation
    • Vereinigung von Segmenten zu einem Ganzen
    • Abstraktion
    • Begriffs- bzw. Klassenbildung

    View Slide

  10. Das Wesen von Software
    Aber wir machen doch OO!
    Seite 10
    • Jein!
    • Object Oriented Programming vs. Object Based and Data
    Centric Programming(DCP)
    • DCP bricht schnell zusammen, weil
    • Prozedural programmiert wird und
    • die Möglichkeiten von OOP nicht ausgenutzt werden
    • «OOP isn’t about creating re-usable classes, it is about
    creating usable classes»

    View Slide

  11. Bausteine Domain-driven Design
    Kommen wir zu Domain-driven Design
    Seite 11
    Ist eine Methode, um Systeme zu modellieren
    verwandt mit Systems Engineering
    Ist kein PM-Vorgehensmodell wie z.B. HERMES
    oder V-Modell
    Hilft uns, Komplexität im Griff zu behalten

    View Slide

  12. Bausteine Domain-driven Design
    Kommen wir zu Domain-driven Design
    Seite 12
    • DDD ist eine Herangehensweise an die Modellierung
    komplexer (objektorientierter) Software
    • Der Begriff wurde von Eric Evans geprägt. Er nennt sich
    selbst einen «Domain Linguist»
    • Es ist mehr als eine Technik oder Methode, es ist eine
    Denkweise zur Steigerung der Produktivität im Umfeld
    komplexer fachlicher Zusammenhänge
    • Der Schwerpunkt des Modells liegt auf Fachlichkeit und
    Fachlogik
    • Das Modell spricht eine eigene, allgegenwärtige
    Sprache, welche von allen Projektbeteiligten verstanden
    wird

    View Slide

  13. Bausteine Domain-driven Design
    Domain-driven Design
    Seite 13
    • ist eine evolvierende Struktur
    • Unser Modell ist nicht von Anfang an perfekt, es lebt und
    wird laufend verfeinert und erweitert
    • definiert ein System
    • und das Zusammenspiel von Teilsystemen mittels
    Schnittstellen und Ereignissen
    • bildet Fachwissen ab
    • durch Einsatz der allgegenwärtigen Sprache

    View Slide

  14. Bausteine Domain-driven Design
    Domain-driven Design
    Seite 14
    • Unterstützt agile Vorgehensweisen
    • Iteratives Vorgehen und schrittweises Verfeinern des
    Modells ist klar gewünscht
    • Das Modell ist nicht nur ein Artefakt
    • es ist ein Kommunikationsmittel zwischen Stakeholdern,
    Lieferanten und Projektmitarbeitern
    • Software = Modell, Modell = Software
    • DDD geht mit jeder Programmiersprache, wird aber
    primär im OO Umfeld eingesetzt

    View Slide

  15. Bausteine Domain-driven Design
    Fangen wir mal an mit dem Webshop
    Seite 15
    • Schritt eins: Bestandsaufnahme und Abgrenzung
    • UML Usecase Diagramm
    uc Use Case Model simplyfied
    Webshop
    Webshop
    «business actor»
    Finanzbuchhaltung
    «business actor»
    Vertrieb
    «business actor»
    Lagerist
    «business actor»
    Kunde
    Quartalsstatistik
    erzeugen
    Artikel pflegen
    Artikel versenden
    Artikel bestellen

    View Slide

  16. Bausteine Domain-driven Design
    Unser Modell wächst
    Seite 16
    • Neue Anforderungen
    • Das wird schnell unübersichtlich
    uc Use Case Model extended
    Webshop
    Webshop
    «business actor»
    Finanzbuchhaltung
    «business actor»
    Kunde
    «business actor»
    Lagerist
    «business actor»
    Vertrieb
    Artikel bestellen
    Artikel pflegen
    Artikel versenden
    Quartalsstatistik
    erzeugen
    Jahresabschluss
    erstellen
    Liquiditätsstatistik
    erstellen
    Inventur durchführen
    Totes Kapital ermitteln
    Tops & Flops ermitteln
    Werbekampagnen
    starten
    Reklamationen
    machen
    Bewertungen abgeben

    View Slide

  17. Bausteine Domain-driven Design
    Was tun?
    Seite 17
    • Schritt zwei: Dekomposition (Zerlegung)
    • DDD nennt das eine Context-Map
    class Context Map
    Geschäftsdomäne
    Finanzbuchhaltung
    (Unter-Domäne)
    Lagerverwaltung
    (Unter-Domäne)
    Webshop
    (Unter-Domäne)
    Vertrieb
    (Unter-Domäne)
    «business actor»
    Finanzbuchhaltung
    «business actor»
    Kunde
    «business actor»
    Lagerist
    «business actor»
    Vertrieb

    View Slide

  18. Bausteine Domain-driven Design
    Was bedeuten die neuen Begriffe
    Seite 18
    • Domain
    • Ist der sog. Problembereich(Problemspace). Hier wird das
    zu lösende Problem oder die zu lösende Aufgabe
    beschrieben
    • Bounded Context
    • Ist der sog. Lösungsbereich(Solutionspace). Ein Bounded
    Context beschreibt, wie eine Funktionalität in der Software
    umgesetzt wird. Ein Bounded Context ist in der Regel ein
    Subsystem oder eigenständiges Lieferobjekt.
    • Domain und Bounded Context sollten sich überlappen

    View Slide

  19. Bausteine Domain-driven Design
    Wir bauen einen Bounded Context
    Seite 19
    • Schritt 3: Reduktion und Abstraktion
    • UML Klassen und Verhaltensdiagramme
    class Lagerverwaltung Bounded Context
    Lagerverwaltung Bounded Context
    Lagerverwaltung Bounded Context
    «Domain Entity»
    Lagerbuchung
    - buchungId :int
    - artikelID :ArtikelID
    - abgangsMenge :int
    «Aggregate Root»
    Lieferung
    - lieferungId :int
    - kundenId :int
    «Value Object»
    Zustellinformationen
    - versandArt :VersandArt
    - anschrift :Anschrift
    «Aggregate Root»
    Lieferungsverfolgung
    - verfolgungsId :int
    - lieferungId :int
    - status :Verfolgungsstatus
    1..*
    «knows»

    View Slide

  20. Bausteine Domain-driven Design
    Was bedeuten die neuen Begriffe
    Seite 20
    • Entity
    • Ein Ding aus der echten Welt, welches eine eindeutige ID
    hat. Ein Entity entspricht nicht einer Datenbanktabelle!
    • Value Object
    • Ist kein Ding, sondern ein Wert wie z.B. ein Geldbetrag oder
    auch eine Postanschrift. Ein Value Object hat keine
    eindeutige ID
    • Aggregate
    • Ein Aggregate sorgt dafür, dass eine Geschäftsregel
    eingehalten wird, z.B. kein Versand ohne Lagerbuchung

    View Slide

  21. Bausteine Domain-driven Design
    Konsequenzen für das Modell
    Seite 21
    • Entities sind keine JavaBeans
    • Nicht jedes Attribut braucht eine Get- und Setmethode. Dies
    würde die Kapselung unterwandern
    • Value Object sind immutable
    • Sie können ihren Zustand nicht verändern und müssen
    immer komplett ersetzt werden. Sehr gut geeignet für Multi-
    Threaded Systeme. Stichwort «Functional Objects».
    • Aggregates kapseln Zugriff
    • Von aussen kann nur auf das Aggregate Root zugegriffen
    werden. Dadurch wird der Zugriff auf komplexe
    Objektgraphen gekapselt und Impl.-Details versteckt.

    View Slide

  22. Bausteine Domain-driven Design
    Das Aggregate, das unbekannte Wesen
    Seite 22
    • Aggregates sind Entities mit zusätzlichen Aufgaben
    • Aggregate = Objektgraph
    • Aggregate verweisen auf andere Aggregate via ID, und
    nicht via Objektreferenz
    • Faustformel: Ein Aggregate kapselt Zugriff auf max. 2-3
    Entities
    • Sinnvoll angewendet führen sie zu weniger
    LazyInitializationExceptions
    • Keine Tuning der Hibernate Mappings mehr nötig, in der
    Regel wird Eager-Loading verwendet

    View Slide

  23. Bausteine Domain-driven Design
    Das sieht dann so aus…
    Seite 23
    class Lagerverwaltung Bounded Context
    Lagerverwaltung Bounded Context
    Lagerverwaltung Bounded Context
    «Domain Entity»
    Lagerbuchung
    - buchungId :int
    - artikelID :ArtikelID
    - abgangsMenge :int
    + getBuchungId() :int
    + getArtikelID() :ArtikelID
    + getAbgangsMenge() :int
    «Aggregate Root»
    Lieferung
    - lieferungId :int
    - kundenId :int
    - status :LieferungStatus
    + getLieferungId() :int
    + getKundenId() :int
    + getZustellinformationen() :Zustellinformationen
    + changeZustellinformationen(Zustellinformationen) :void
    + getLieferungStatus() :LieferungStatus
    «Value Object»
    Zustellinformationen
    - versandArt :VersandArt
    - anschrift :Anschrift
    + getVersandArt() :VersandArt
    + getAnschrift() :void
    «Aggregate Root»
    Lieferungsverfolgung
    - verfolgungsId :int
    - lieferungId :int
    - status :Verfolgungsstatus
    + getVerfolgungsId() :int
    + getLieferungsId() :int
    + getVerfolgungsstatus() :Verfolgungsstatus
    1..*
    «knows»

    View Slide

  24. Bausteine Domain-driven Design
    Und nicht so…
    Seite 24

    View Slide

  25. Bausteine Domain-driven Design
    Der Lebenszyklus von Objekten
    Seite 25
    • Entities und Aggregates werden von Factories oder
    Buildern erzeugt. Ein direkter Aufruf von «new» ist
    verboten
    • Entities und Aggregates werden über Repositories
    persistiert
    • Entities und Aggregates können über Repositories
    rekonstituiert werden
    • Ein Repository ist kein DAO, da es Teil des Fachmodells
    und kein technisches Artefakt ist

    View Slide

  26. Bausteine Domain-driven Design
    Das sieht dann so aus…
    Seite 26
    class Domain Object Lifecycle
    «Aggregate Root»
    Lieferung
    - lieferungId :int
    - kundenId :int
    - status :LieferungStatus
    + getLieferungId() :int
    + getKundenId() :int
    + getZustellinformationen() :Zustellinformationen
    + changeZustellinformationen(Zustellinformationen) :void
    + getLieferungStatus() :LieferungStatus
    «Factory»
    LieferungFactory
    + createLieferung(int) :Lieferung
    LieferungBuilder
    + fuerKunde(int) :LieferungBuilder
    + build() :LieferungBuilder
    «interface»
    LieferungRepository
    + add(Lieferung) :void
    + get(int) :Lieferung
    + sucheMitKundenId(int) :Lieferung
    + sucheNachStatus(LieferungStatus) :Lieferung
    «creates»
    «creates»
    «persist,reconstitute»

    View Slide

  27. Bausteine Domain-driven Design
    Ein kompletter Anwendungsfall
    Seite 27
    • Die Umwelt muss mit den Bounded Contexten
    interagieren
    • Der Bounded Context stellt dafür Schnittstellen zur
    Verfügung
    • Diese Schnittstellen heissen Domain Services
    • Ein Domain Service verhält sich wie eine Fassade, er
    kapselt Komplexität

    View Slide

  28. Bausteine Domain-driven Design
    Beispiel: Versand einer Lieferung
    Seite 28
    class Beispiel Lieferung versenden
    «Domain Service»
    LieferungDomainService
    + createLieferung(LieferungSpecification) :LieferungId
    «Factory»
    LieferungFactory
    + createLieferung(KundenId) :Lieferung
    LagerbuchungFactory
    + createLagerbuchung(ArtikelID, int) :Lagerbuchung
    «Aggregate Root»
    Lieferung
    - lieferungId :LieferungId
    - kundenId :KundenId
    - status :LieferungStatus
    + getLieferungId() :LieferungId
    + getKundenId() :KundenId
    + getZustellinformationen() :Zustellinformationen
    + changeZustellinformationen(Zustellinformationen) :void
    + getLieferungStatus() :LieferungStatus
    + addLagerbuchung(LagerbuchunfFactory, ArtikelID, Int) :void
    «Domain Entity»
    Lagerbuchung
    - buchungId :int
    - artikelID :ArtikelID
    - abgangsMenge :int
    + getBuchungId() :int
    + getArtikelID() :ArtikelID
    + getAbgangsMenge() :int
    «interface»
    LieferungRepository
    + add(Lieferung) :void
    + get(LieferungId) :Lieferung
    + sucheMitKundenId(KundenId) :Lieferung
    + sucheNachStatus(LieferungStatus) :Lieferung
    «creates»
    1..*
    «creates»
    «use»
    «persist,reconstitute»

    View Slide

  29. Bausteine Domain-driven Design
    Ein paar Worte zur Objektorientierung
    Seite 29
    • Ein Name ist ein Name und kein String
    • Immutable Objects bevorzugen
    • Soviel Logik wie möglich in Value Objects packen
    • Command-query separation einhalten(CQS Principle)
    • Lesender Code liefert ein Ergebnis und ist nicht destruktiv
    • Schreibender Code verändert einen Zustand, ist aber immer
    vom Typ void. Aussnahme : Domain Services
    • Eigenständige Methoden für lesenden und schreibenden
    Code
    • Single responsibility principle einhalten(SRP)

    View Slide

  30. Schichtenarchitektur mal anders
    Die klassische Schichtenarchitektur
    Seite 30
    • Beispiel für strikte Schichtentrennung
    • Transitive Abhängigkeiten sind auch Abhängigkeiten
    • Geschäftslogik ist indirekt abhängig von der Infrastruktur
    • Stammt noch aus J2EE Zeiten(1999)
    cmp Klassische Schichten
    User Interface Layer
    + LieferungPresenter
    + LieferungView
    + LieferungViewModel
    Business Layer
    + LieferungService
    Data Access Layer
    + LieferungDAO
    + hibernate
    Infrastructure Layer
    + DataSource

    View Slide

  31. Schichtenarchitektur mal anders
    IoC mit hexagonale Architektur
    Seite 31
    • So sieht es aus in der DDD-Welt
    • Entspannte Schichtenarchitektur, Einsatz von CDI
    • Entity != DTO
    • Domain Model ist technologieneutral
    class DDD Schichten
    Domain Layer
    + Lagerbuchung
    + LagerbuchungFactory
    + Lieferung
    + LieferungDomainService
    + LieferungFactory
    + LieferungRepository
    Application Layer
    + LieferungDTO
    + LieferungService
    + LieferungSpecification
    User Interface Layer
    + LieferungPresenter
    + LieferungView
    + LieferungViewModel
    + SessionManager
    Infrastructure Layer
    + HTTPSessionSessionManagerImpl
    + LieferungRepositoryHibernateImpl
    + LieferungRESTResource
    + LieferungSOAPWebService

    View Slide

  32. Messaging und WebServices
    Integration von Unter-Domänen
    Seite 32
    • Abruf von Lagerbestand Webshop -> Lagerverwaltung
    • Bestellung versenden Webshop -> Lagerverwaltung
    class Context Map
    Geschäftsdomäne
    Finanzbuchhaltung
    (Unter-Domäne)
    Lagerverwaltung
    (Unter-Domäne)
    Webshop
    (Unter-Domäne)
    Vertrieb
    (Unter-Domäne)
    «business actor»
    Finanzbuchhaltung
    «business actor»
    Kunde
    «business actor»
    Lagerist
    «business actor»
    Vertrieb

    View Slide

  33. Messaging und WebServices
    Konzeptionelle Möglichkeiten
    Seite 33
    • Synchrone Abfrage(blockierender Aufruf)
    • Nutzung von SOAP oder REST
    • REST bevorzugen, da durch Proxy-Server
    cachebar(Stichwort etag und expiry-time im HTTP Header)!
    • Asynchrone Abfrage(nicht blockierend)
    • Nutzung von JMS oder AMQP
    • Immer Double-Dispatch von Nachrichten, da Messaging
    System nicht verfügbar sein kann

    View Slide

  34. Messaging und WebServices
    Synchroner Aufruf(Beispiel)
    Seite 34
    • REST oder SOAP?
    • Abfrage des Lagerbestandes ist häufig
    • Muss das immer neu berechnet werden?
    • Können wir das nicht cachen?
    • REST GET Request bevorzugen, z.B.
    http://mydomain/artikel//bestand.json
    • Kann von Proxy-Servern gecached werden, Stichwort
    Etag und Expiry-Time

    View Slide

  35. Messaging und WebServices
    Ansynchroner Aufruf mit DDD
    Seite 35
    • DDD kennt das Konzept von sog. Domain Events
    • Ein Domain Event ist ein fachliches Ereignis, z.B. Kunde
    hat Bestellung aufgegeben
    • Domain Events werden von einem Bounded Context
    produziert und können von anderen Bounded Contexten
    konsumiert werden
    • Aber Achtung: Events müssen gecached werden, da z.B.
    auch die Messaging Middleware nicht verfügbar sein
    kann. Daher immer Double-Dispatch!
    • Events immer mit Zeitstempel und eindeutiger ID. So
    kann Reihenfolge und Verarbeitung protokolliert werden

    View Slide

  36. Messaging und WebServices
    Ansynchroner Aufruf(Beispiel)
    Seite 36
    • Event wird von einem Aggregate erzeugt und in einem
    EventRepository persistiert
    • Im Infrastructure Layer gibt es einen Timer, welcher das
    EventRepository ausliest und bei Verfügbarkeit der
    Messaging Middleware(JMS / AMQP) weiterleitet
    • In konsumierenden Bounded Context gibt es im
    Infrastructure Layer einen MessageListener, welcher auf
    Nachrichten hört
    • Diese Nachrichten werden via ApplicationService an die
    Geschäftslogik übergeben. Deshalb muss Infrastructure
    Layer auch ganz oben und nicht ganz unten sitzen!

    View Slide

  37. Weiterführende Themen
    Weitere Begriffe der DDD-Welt
    Seite 37
    • Open-host Service(OHS)
    • Ist eine Sammlung von Services, welche von einem
    Bounded Context zur Verfügung gestellt werden
    • Anti-corruption Layer(ACL)
    • Adapter von einem Bounded Context für den Zugriff auf den
    OHS eines anderen Bounded Context
    • Generic Subdomain
    • Beinhaltet gemeinsame Typen, wie z.B. KundenId oder
    ArtikelID, aber keine Geschäftslogik

    View Slide

  38. Weiterführende Themen
    Der JavaBean Mythos
    Seite 38
    • Die JavaBean Spezifikation wurde ursprünglich für GUI
    Widgets erstellt
    • 0-Arg Konstruktor
    • Public Getter und Setter für Properties
    • Optionale BeanInfo Klassen
    • Niemand sagt, dass alles eine JavaBean sein muss!
    • Hibernate kann seit Version 2 auch Field-Access, keine
    Setter und Getter mehr notwendig, JPA kann das auch
    • Es reicht auch ein Package-Visibility 0-Arg Konstruktor

    View Slide

  39. Weiterführende Themen
    Weiterführende Themen
    Seite 39
    • Viele statische Strukturen wie z.B. Interfaces und
    Domänenobjekte können aus dem Modell generiert
    werden
    • Für Enterprise Architect gibt es die MDG Erweiterungen
    • Dadurch bleibt Modell und Code synchron
    • Für dynamisches Verhalten ist UML eher ungeeignet
    • Die DDD Prinzipien können auf alle OO-Sprachen
    übertragen werden, DDD unterstützt auch funktionale
    Programmierung
    • Arc42 Framework für Dokumentationen

    View Slide

  40. Zusammenfassung
    Seite 40
    Domain-driven Design führt zu stabilen und
    langfristig wartbaren Systemen
    DDD ist kompatibel zu Agilen Methoden
    DDD ist nicht schwer und macht Spass!

    View Slide

  41. Fragen ?
    Seite 41

    View Slide

  42. Weiterführende Themen
    Lektüre zum Lesen
    Seite 42

    View Slide

  43. Herzlichen Dank!
    Seite 43

    View Slide