Transcript

Domain-Driven Design

Überblick über Strategic und Technical Design mit DDD

In dieser Folge des innoQ Podcasts spricht Lucas Dohmen mit Michael Plöd über Domain-Driven Design. Was ist Domain-Driven Design? Wie passt es zusammen mit anderen Ansätzen wie Agile, DevOps oder Microservices? Was ist die Ubiquitous Language und welche Rolle spielt sie in DDD? Was ist das Strategic Design und was bedeuten die Begriffe Bounded Context und Context Map? Und was ist das Technical Design und welche Begriffe begegnen einem dort?

Back to episode

Transcript

Michael Plöd: Hallo Lucas.

Lucas Dohmen: Magst du uns ganz kurz sagen, wer du bist und was du bei innoQ so machst?

Michael Plöd: Ja, klar. Mein Name ist Michael Plöd, ich bin Principal Consultant bei der innoQ und bin als solcher auf der einen Seite für Kunden verantwortlich, bin aber auch selbst relativ aktiv in Projekten unterwegs und halte auch Schulungen zu dem Thema Domain-driven Design und verwende Domain-driven Design seit den Jahren 2005/6 recht aktiv ganz gerne als Werkzeug in meinem Projektgeschäft.

Lucas Dohmen: Da kannst du direkt mal damit loslegen: Was genau ist denn dieses Domain-driven Design? Und was ist die Motivation, die uns dazu geführt hat, solche Sachen zu machen?

Michael Plöd: Ich sage mal, Domain-driven Design lässt sich jetzt eigentlich nicht als ein einziges Ding beschreiben. Das ist eigentlich eher eine Ansammlung an Praktiken, Einstellungen und auch Patterns und Betrachtungsweisen für verschiedene Aspekte in dem Prozess der Softwareentwicklung. Die Motivation ist eigentlich die, dass man im Laufe der Zeit erkannt hatte, dass dieses typische Wasserfallmodell à la Fachbereich schreibt Spezifikation, Entwicklung motzt über die Spezifikation, implementiert sie dann aber doch und am Schluss stellt der Fachbereich fest, dass das, was entwickelt wurde, eigentlich nicht das ist, was er eigentlich gebraucht hat, dass es irgendwie nicht tragfähig ist.

Das ist ja auch eine ähnliche Story, die in der Agile Community recht stark getrieben wird und da setzt sich Domain-driven Design eigentlich auch drauf und sagt, Entwicklung und Fachbereich sollen näher zusammenrücken und intensiver über fachliche Probleme reden. Das heißt natürlich auf der einen Seite, dass die Entwickler viel, viel tiefer in die Fachlichkeit eindringen sollten. Sie sollten vielleicht, wenn ich jetzt ein Baufinanzierungsprojekt mache, sich vielleicht mit dem Thema Baufinanzierung auf einer fachlichen Ebene beschäftigen. Das Gleiche gilt natürlich auch mit dem Fachbereich, der sollte natürlich auch näher an die IT ranrücken. Das heißt aber jetzt natürlich nicht, dass plötzlich Business-Analysten oder Fachbereichsleute programmieren sollen, sondern es soll einfach ein näheres Zusammenrücken an der Stelle stattfinden.

Und da setzt Domain-driven Design auf ein paar Ebenen auf. Das ist auf der einen Seite die ubiquitous language, also eine einheitliche, verbindliche Sprache in bestimmten Bereichen des Projekts, also in den Kontexten eines Projekts. Das geht über das strategic design, welches das große Ganze von verschiedenen systemnahen Systemlandschaften, Anwendungslandschaften, Anwendungen betrachtet bis hin zum technical design, wo ganz konkrete Designpatterns, Entwurfsmuster oder eben Konstrukte für die Implementierung spezifischer Logiken propagiert werden.

Lucas Dohmen: Du hattest eben kurz erwähnt: Agile. Wo siehst du da den Zusammenhang oder das Zusammenspiel zwischen Domain-driven Design und agile?

Michael Plöd: Das ist eine gute Frage. Am Ende des Tages sehe ich es, ehrlich gesagt, so, dass Domain-driven Design eine perfekte Ergänzung zu agilen Praktiken ist. Es heißt, Domain-driven Design erkennt auch, und das sieht man eigentlich auch ganz stark insbesondere, wenn man das Buch von Eric Evans liest, das quasi den Stein ins Rollen brachte vor einigen Jahren, dass, sage ich mal, es absolut akzeptiert ist, dass man nicht zu Beginn eines Projektes alles über eine bestimmte Fachdomäne wissen kann. Das fängt beim Fachbereich an. Ich habe das selber häufig erlebt, dass praktisch die IT Spezifikationen wollte, der Fachbereich gesagt hat, wir können euch die einfach noch nicht liefern, wir müssen in das Problem tiefer eintauchen. Und dieses gemeinsame tiefere Eintauchen, das konstante Refactoring oder, wie es in dem Buch von Eric Evans so schön heißt, das refactoring toward deeper insight sind Kernbestandteile und das passt eigentlich perfekt mit den ganzen agilen Prinzipien eben zusammen: Dass ich quasi tiefer in die Fachlichkeit eintauche, den Kunden berücksichtige und laufend Software liefere, die einen Mehrwert für den Kunden schafft.

Lucas Dohmen: Das heißt also, das Entwicklungsteam und das Fachteam, die erforschen gemeinsam quasi das Problem, die Domäne.

Michael Plöd: Ich denke mal, das hört sich jetzt sehr idealistisch an, diese Aussage, und ich sage jetzt mal, das ist jetzt nicht ein Jugend forscht-approach, wo ich jetzt quasi nach dem Motto, schauen wir mal, was rauskommt agiere. Aber es ist so, dass es quasi akzeptiert ist, dass man plötzlich erkennt: Ah, okay, wir haben jetzt plötzlich eine tiefere Erkenntnis über unseren Markt erlangt, über unsere Domäne erlangt und dass ich das eben auch im Design der Software widerspiegele. Ich sage jetzt mal so, das Herz der Domäne sollte eigentlich auch ein Kernstück des Designs der Software zu einem gewissen Grad sein.

Lucas Dohmen: Und gibt es auch einen Zusammenhang zu der DevOps Bewegung oder siehst du das als vollständig unabhängig?

Michael Plöd: Naja, ich sage mal, das geht eigentlich alles halbwegs Hand in Hand. Natürlich ist es so, dass Domain-driven Design und DevOps erst mal überhaupt nichts miteinander zu tun haben. Aber wenn ich dieses ganze Feld ein bisschen näher betrachte, finde ich eigentlich, dass die sich wunderbar ergänzen. Auf der einen Seite sagt DevOps, dass der Betrieb und die Entwicklung näher zusammenwachsen sollen, dass ich quasi ein Team habe, das eigenverantwortlich hergeht, Software entwickelt und betreibt und weiter pflegt. Auf der anderen Seite habe ich Domain-driven Design, das propagiert Fachbereich und Entwicklung sollen näher zusammenrücken und in dem Design der Software enger zusammenarbeiten.

Auf die Spitze getrieben formuliert könnte ich sagen, dass man behaupten könnte, dass Domain-driven Design durchaus propagiert, dass es super wäre, wenn fachliche Mitarbeiter Teil eines Teams sind. Wenn ich das jetzt eins und eins zusammenzähle und die zwei Puzzelteilchen zusammensetze, komme ich eigentlich schon in einer idealen Welt dahin, dass ich ein Team habe, welches Software erstellt, spezifiziert, betreibt, ausrollt und so weiter und so fort. Und dadurch komme ich zu der, und da kommen wir wieder zu dem agile-Bereich, Produktdenke, die ich eigentlich will. Ich will ja eigentlich wegkommen von so einer Milestone-Projektdenke in Richtung einer Produktdenke in den IT-Projekten. Ich finde, obwohl es jetzt so explizit nicht beschrieben steht oder ausformuliert ist, finde ich eigentlich schon, dass das ganz gut zusammenpasst.

Lucas Dohmen: Du hattest eben schon erwähnt, dass Domain-driven Design nicht einfach eine Sammlung von Patterns ist. Du hattest unterschieden zwischen dem Strategic Design und dem Technical Design. Ich würde sagen, wir fangen mit dem Strategic Design an. Magst du da mal kurz ein paar Begriffe erklären, was da so einem begegnet.

Michael Plöd: Ich sage mal so: Salopp formuliert kann man sagen, dass es beim Strategic Design erst mal um das große Ganze geht, das heißt, die Gesamtheit eines Systems oder einer Systemlandschaft. Faktisch basiert Strategic Design erst mal auf einem Konstrukt namens Bounded Context und den Domänen und Subdomänen. Die Domäne, das ist sozusagen der ganz große Rahmen, die Subdomänen sind dann die ersten Untergliederungen. Ich könnte beispielsweise sagen, meine Domäne ist Banking, ich habe da die Subdomänen Produkte, Vertriebskanäle, Marketing usw. und jetzt beispielsweise bei den Vertriebskanälen weitere Subdomänen Filialen, Automaten, Call Center, Online, Apps usw. Und bei den Produkten Einlage- und Auslageprodukte, wie Girokonten auf der Einlageseite, auf der Auslageseite so etwas wie Kredite. Das sind sozusagen meine Subdomänen. Und wenn ich jetzt beispielsweise immer Baufinanzierung als Subdomäne betrachte, kann ich diesen Teil eigentlich weiter untergliedern in einzelne fachliche Teilbereiche, beispielsweise so etwas wie eine Antragserfassung, so etwas wie das Abholen einer Schufa-Auskunft, die Entscheidung über einen Kredit samt vielleicht irgendwelcher Scoring-Regeln usw. Und dort kann ich Bounded Context schneiden.

Und der Bounded Context, das ist jetzt etwas, sagen wir mal so, ich habe schon relativ häufig gehört, das Domain-driven Design ist doch eigentlich alter Wein in neuen Schläuchen. Das stimmt so nicht ganz. Natürlich propagiert Domain-driven Design eigentlich nichts anderes als ein seriöses Software-Engineeringtum. Aber der Bounded Context, der hat ein ganz bestimmtest Alleinstellungsmerkmal. Und zwar ist der Bounded Context erst einmal eine fachliche Klammer um eine bestimmte Fachlichkeit. Aber - und das ist das ganz wichtige - er ist auch die Grenze und die Gültigkeit eines bestimmten Modells. Das heißt, es ist eigentlich ein ganz stark dezentrales Architekturkonstrukt, das geht eigentlich ganz stark weg von Zentralisierungsbestreben. Ich gehe weg von einem, jenem zentralen Kundenservice oder CAM-service, der unternehmensweit verpflichtend ist. Das ich quasi sage, ich behandele Kunden im Kontext A anders als in einem Kontext B.

Nehmen wir beispielsweise die Registrierung für eine Softwareentwicklungskonferenz. An der Stelle kann ich quasi sagen, dass ich in der Reservierung den Kunden sehr natürlich, persönlich modelliere, aber jetzt beispielsweise, wenn es um das Eventmanagement geht, wo mich interessiert: Was sind die Essenspräferenzen meiner Besucher, um das Catering bestellen zu können. Oder welche Referenten setze ich in welche Räume, je nach Beliebtheit der Referenten oder der Themen, die diese haben. Da interessiert mich der einzelne Kunde relativ wenig, sondern da geht es eigentlich eher darum, dass ich sage, so und so viele, also die Anzahl, oder ich habe einmal. Oder ich habe das in einem Kontext mal sehr mathematisch, Rule Engine geprägtes Modell, in den anderen vielleicht ein eventgetriebenes Modell, das also auf fachlichen Ereignissen basiert, und in anderen vielleicht eher ein formularbasiertes Modell, das ganz stark auf eine relationale Datenbank passt. Und das ist dann der bounded context.

Lucas Dohmen: Okay. Magst du noch einordnen, wo du dann die Sprache siehst? Du hast am Anfang über die generelle Sprache gesprochen. Wo siehst du die? Ist die innerhalb eines Kontexts oder ist die über das ganze Unternehmen hinweg? Wie funktioniert das?

Michael Plöd: Genau, diese generelle Sprache heißt im Domain-driven Design Ubiquitous Language. Das soll eine Sprache sein, die insbesondere innerhalb eines Kontexts für alle Stakeholder verpflichtend ist. Das heißt, sowohl für den Fachbereich, die Entwickler, aber natürlich auch für den Code. Das heißt, es kann nicht angehen, dass wir auf Deutsch spezifizieren, auf Deutsch irgendwelche Wiki-Einträge schreiben, irgendwelche Bug-Tickets verfassen und dann werden deutsche Fachbegriffe auf Ebene der Entwicklung per Google Translator oder dict.leo.org oder so was ins Englische übersetzt. Da habe ich schon einen Sprach Bruch zwischen Spezifikation und Code an der Stelle. Und das ist etwas, was die Ubiquitous Language eben zu adressieren versucht. Dass wir sozusagen sprachlich genauer und präziser und auch verbindlicher agieren.

Lucas Dohmen: Das bedeutet also, alle, vom Kunden bis zum Entwickler, sprechen dieselbe Sprache mit gleichem Kontext?

Michael Plöd: Das möchte ich erreichen damit, das wäre die ideale Welt.

Lucas Dohmen: Okay. Ein weiterer Begriff, den ich in dem Kontext gehört habe, ich die Context Map. Was ist das?

Michael Plöd: Die Context Map ist ein Konstrukt, welches dazu genutzt wird, um Interaktionspunkte zwischen verschiedenen Bounded Context zu betrachten. Ein Bounded Context kann ein Softwaremodul sein, es kann auch eine eigenständige Applikation sein, ein Microservice oder eine gesamte Applikation an der Stelle in der Betrachtung. Und ich möchte dort betrachten, wie quasi Modelle propagiert werden von einer Applikation zur nächsten oder von einem Bounded Context zum nächsten Bounded Context.

Das ist für mich ein extrem interessantes Konstrukt, gerade im Umfeld von Transformationsprojekten. Was ich an der Stelle relativ häufig sehe, ist, dass ganz viele Transformationen geplant werden, die werden gestartet, man will Software modernisieren, neu gestalten, restrukturieren etc. und nach einem halben Jahr sieht man, salopp formuliert, einen Haufen bedröppelter Gesichter in einem Lenkungsauschuss-Meeting sitzen: Ups, wir müssen plötzlich irgendeine andere Applikation auch noch anpassen, das haben wir völlig übersehen. Warum laufen viele Projekte in diese Situation hinein? Einer der Gründe dafür ist es, dass quasi auf Ebene der Enterprise-Architektur häufig eigentlich nur Liefer- und Leistungsbeziehungen zwischen Systemen betrachtet werden. Das heißt, irgendein System, sagen wir ein Scoring-Modul, ruft die Schufa auf. Aber es wird nicht betrachtet, was denn mit dem Modell der Schufa gemacht wird, das quasi über die Schnittstelle kommt. Wie wird denn das konsumiert? Wird das einfach blind übernommen oder wird das übersetzt in ein eigenes Modell oder sind die eigentlich extrem lose gekoppelt, agieren die sehr entkoppelt über Events, Messaging etc. Das ist eine Facette.

Die andere Facette sind organisatorische Aspekte. Das heißt: Ist ein Team sehr aggressiv und eskaliert relativ schnell bei Modell- oder Schnittstellenänderungen von dem bereitstellenden Team und hat quasi da einen Einfluss oder ist es tendenziell, aus welchen Gründen auch immer, eher in der Defensive. Das heißt, es muss entweder das Zeug einfach übernehmen, was es bekommt, oder es will das auch übernehmen, weil es das einfach auch ganz gut findet. Das heißt, die Context Map erweitert quasi die Betrachtung auf Liefer- und Leistungsbeziehungsebene, um, ich sage jetzt mal organisatorische, politische, aber natürlich auch um modellspezifische Ebene, also wie das Modell konsumiert wird. Die Context Map verordnet diese Beziehung anhand von sieben Mustern, die auftreten. Das ist einmal beispielsweise separate ways, anti-corruption layer, customer supplier, conformist, die published language, der open host service oder zum Beispiel ein shared kernel.

Lucas Dohmen: Okay. Ich glaube, wir gehen jetzt nicht in jedes von diesen Pattern zu tief rein?

Michael Plöd: Nee, das würde ich nicht machen. Aber ich würde noch ganz gern einen Punkt dazu sagen. Das ist ein super Ausgangspunkt, wenn ich Software modernisieren will. Oder wenn ich beispielsweise aus Monolithen Microservices rauslösen will. Wenn ich da mal so eine Context Map für einen spezifischen Rahmen aufzeichne, kann ich diese Transformation, sage ich jetzt mal, mit mehr Vorhersagbarkeit durchführen. Und ich finde, das ist eigentlich ein sehr interessantes Vehikel für bestehende Software. Es ist jetzt kein Upfront-Design-Ding, sondern eher etwas, was auf bestehender Software fußt. Aber die einzelnen Patterns müssen wir jetzt nicht im Detail durchgehen.

Lucas Dohmen: Magst du vielleicht eins beispielsweise durchgehen, wie man sich darunter etwas vorstellen kann?

Michael Plöd: Nehmen wir mal ein Modell, das ist der Customer Supplier. Beim Customer Supplier habe ich ein konsumierendes System und ein bereitstellendes System oder Team, also einmal den Customer und einmal den Supplier. Man nennt das auch Upstream-Downstream-Team oder -System im Domain-driven Design, wobei das bereitstellende System das Upstream-System ist, das konsumierende das Downstream-System. Weil nämlich das Modell von Upstream nach Downstream fließt wie bei einem Fluss. Jetzt beim Customer Supplier ist es so, dass die sich sehr intensiv miteinander austauschen über das Modell, das da kommt. Dass das Downstream-Team eigentlich einen sehr starken Einfluss auf das Modell des Upstream-Teams hat. Die haben beispielsweise ein Vetorecht an der Stelle. Das sieht man sehr schön, aus quasi einer schnöden Liefer- und Leistungsbeziehung, wieviel tiefer Domain-driven Design an der Stelle eintaucht, weil es halt organisatorische Aspekte, politische Aspekte etc. berücksichtigt.

Lucas Dohmen: Und siehst du da noch andere Sachen im Strategic Design oder ist das für dich jetzt erst mal alles?

Michael Plöd: Also für mich sind das eigentlich so die wichtigsten Aspekte. Natürlich geht das Ganze auch noch weiter: Darin sind noch Aspekte wie: Wie skaliere ich das Ganze. Für mich ist das Strategic Design - ich vermute mal, da werden wir uns auch heute noch drüber unterhalten - ein ganz relevanter Teil für die Strukturierung von Microservice-Landschaften. Gerade auch, wenn ich jetzt auf das Separate Ways-Muster sehe, was ja etwas ist, was ich mit Microservices erreichen will, möglichst starke Entkopplung, wie komme ich denn dahin etc., da finde ich das Strategic Design sehr, sehr interessant ist.

Lucas Dohmen: Dann lass uns doch erst, bevor wir darauf eingehen, erst noch kurz über das Technical Design sprechen. Da gibt es verschiedene Muster, glaube ich, oder was macht das Technical Design? Oder was ist überhaupt Technical Design?

Michael Plöd: Technical Design, das ist sozusagen der interner Aufbau eines Kontexts. Man spricht manchmal auch von den sogenannten Internal Building Blocks an der Stelle. Das heißt, wo Strategic Design eher mal das große Ganze betrachtet und ein Kontext quasi eher so eine Blackbox ist, wechsele ich im Technical Design in eine Whitebox-Sicht. Das kennt an der Stelle verschiedene Muster, wie ich einen Kontext intern ausgestalten kann. Also beispielsweise das ganz wichtige Dreigespann sind Entities, Value Objects und Aggregates. Das sind so mal die ersten Konstrukte des Technical Designs.

Entities sind zum Beispiel Modellelemente, die eine konstante Identität haben, die sehr sehr langfristig ist, beispielsweise eine Kundennummer, eine Bestellungsnummer, eine Kontonummer oder so etwas. Und die tendenziell einen eigenen Lebenszyklus haben. Im Gegensatz dazu sind die Value Objects eher zweitrangig, sie sind weniger zentral für den Kontext, aber sie sind dennoch natürlich wichtig. Der wichtigste Unterschied an der Stelle ist es, dass ein Value Object, dass sich dessen Identität eigentlich nicht an so einem langfristigen Identifier festmacht, sondern eher an der Ausprägung der Attribute. Also zum Beispiel, wenn ich jetzt einen Online Shop betrachte, der Preis eines Produkts, dessen Währungsbetrag. Das ist irgendwie eine Zahl und eine Währung, quasi zehn Euro, zwölf Dollar, 120 Pfund oder so etwas. Dann kann ich sagen, das ist ein Value Object, weil mich an der Stelle eigentlich nur die Ausprägung der Attribute interessiert. Auf der anderen Seite, wenn ich jetzt einen Zehn-Euro-Schein betrachte und den mal im Kontext einer Geldscheindruckerei bei der Bundesdruckerei betrachte, dann betrachte ich diesen einen jenen ganz spezifischen Zehn-Euro-Schein und da ist der natürlich eine Entity.

Und das sehen wir ganz schön: Es ist je nach Kontext abhängig, ob ich irgendetwas als Entity oder als Value Object betrachte. Da sieht man auch wieder diese Logik des Bounded Contexts schön: Der ist die Grenze und die Gültigkeit eines Modells. Also beispielsweise ein Adressaufkleber auf einem Paket bestehend aus Name, Vorname, Straße, Postleitzahl, Stadt, da kann quasi der Name, Vorname aus einem Kunden kommen, der Kunde kann irgendwo eine Entity sein, aber die Adresse ist einfach ein Value, weil wir mit der Adresse nichts weiter machen wollen. Aber beim Versanddienstleister könnte ich die Adresse eigentlich eher als Entity betrachten, weil die eigentlich das führende Element ist an der Stelle. Und wenn wir diese Kombination aus Name, Vorname betrachten, da geht es eher darum, wo der Paketbote oder die -botin die Klingel drückt.

Aber jetzt nur mit Entities oder Value Objects zu arbeiten greift eigentlich auch zu kurz. Wir brauchen eigentlich noch eine weitere Untergliederung und da kommen die Aggregates zum Tragen. Die Aggregates sind sozusagen noch mal innerhalb eines Kontexts weitere Klammern um Entities und Value Objects. Sagen wir mal, an der Stelle hat sich die Wahrnehmung im Laufe der Zeit in der Domain-driven Design-Community in meinen Augen ein bisschen gewandelt. In den Anfangstagen von Domain-driven Design betrachtete man eigentlich das Aggregate primär aus dem Konzept der Root Entity heraus. Das heißt, das ist die Kopf-Entity in einem Aggregate unter der weitere Entities hängen können und andere Value Objects hängen können und die quasi den Lebenszyklus des Aggregats steuert. Das heißt, die machten sozusagen ein Override auf den Lifecycle von anderen Entities. Auf der anderen Seite ist die Root Entity auch der einzig erlaubte Einsprungspunkt in ein Aggregat rein. Also, ich darf eine andere Entity von außen nicht referenzieren.

Das sind so die wichtigsten Punkte gewesen, wie man früher das Ding betrachtet hat. Das ist natürlich heute nach wie vor gültig, wobei ich heute eher eine Tendenz dazu sehe, dass man zu kleineren Aggregaten übergeht, worin eigentlich meistens eine Entity steckt und ein paar Value Objects und eigentlich eher so Themen wie transaktionale Trennung, die Art und Weise, wie ich von Aggregate zu Aggregate referenziere eher hervorhebt. Beispielsweise, dass ich eben nicht sage, ich möchte eine direkte Referenz auf die andere Root Entity von dem Aggregate haben, sondern eher auf den Identifier der Root Entity und lade dann die Root Entity explizit nach oder ziehe mir die quasi explizit noch mal. Und gerade auch der Aspekt, dass ich, wenn ich zwei Aggregates updaten will oder inserten will oder was weiß ich was jetzt, wenn ich mal in eine Datenrichtung denken möchte, dass ich das quasi zwei getrennten Transaktionen unter dem Konzept der Eventual Consistency eben tun werde. Das ist eigentlich eher so ein Treiber, der heute sehr prominent diskutiert wird.

Es gibt noch weitere Building Blocks, da sind beispielsweise die Repositories zu nennen, die sich sozusagen um die Persistenz kümmern. Und das ist ganz wichtig an der Stelle: Die Domain-driven Design_-Entities_ und -Value Objects sind erst mal keine Persistenzmodelle, sondern es sind Fachmodelle. Und das ist auch etwas, was häufig falsch verstanden wird. Das die auch direkt verwendet werden für Persistierung. Ich sage mal so: Kann ich machen, würde ich aber gerade in komplexeren Systemen tendenziell vermeiden. Für mich hat dann ein Repository vielleicht noch mal ein eigenes Persistenzmodell, quasi on-top als Add-on zu dem Fachmodell und das kümmert sich dediziert um so etwas wie Persistierung, wie Persistenz usw. Und das Respository, das beinhaltet quasi den ganzen Datenzugriffs-Code, die Data Storages, Caching Systeme usw. Das ist eigentlich ein sehr weit gefasster Begriff, wobei man es auf einer Implementierungsebene meistens als Datenzugriffsschicht betrachtet. Also, wenn ich jetzt mal das Repository in Spring Data beispielsweise auf einer Implementierungsebene anschaue, ist das eigentlich eher so ein Data Access Layer, aber eigentlich gehört da noch ein bisschen mehr dazu, was ja auch wieder in die Microservice-Story ganz gut reinpasst.

Ein Microservice sollte seine eigene Datenhaltung haben. Ich empfehle immer wieder: Scoped ein Repository auf Ebene von einem Aggregate und wenn ich an der Stelle sage, dass Repository hat auch eine Datenhaltung, komme ich eigentlich auch zu dem Schluss, dass ich gegebenenfalls unterschiedliche Datenhaltungen für verschiedene Aggregates haben kann. Was noch dazu kommt, sind die Application Services. An der Stelle muss man ganz klar sagen, ich möchte eigentlich möglichst viel Fachlogik auf Ebene meiner Entities, Value Objects und Aggregates verorten. Aber ich habe natürlich orchestrierende Logik, Orchestrierungsaufgaben, Security usw. Und das würde ich dann tendenziell in Application Services auslagern.

An der Stelle, wenn ich sozusagen Logik habe, die zwei Aggregates betrifft, brauche ich irgendetwas dazwischen, weil die sich ja eigentlich nur by Identifier und keine direkte Referenz aufeinander haben. Und das ist der Punkt, bei dem ich Application Services ansetzt. Und dann gibt es noch die Factories, wobei ich sage, das ist so der unspannendste Teil, die Factory im Sinne von Domain-driven Design deckt sich eigentlich mit der Gang of Four-Factory, mit der Factory, mit dem Factory-Pattern und der Idee dahinter relativ stark. Und was jetzt in den letzen Jahren noch sehr stark aufkam ist das Konstrukt des Domain Events, des fachlichen Ereignisses, dass ich das immer mehr stärker in den Vordergrund rücke, dass ich eben sage, es gibt bestimmte Ereignisse, die passiert sind, die sind auch in der Vergangenheitsform notiert und die sehe ich eigentlich auch noch meist in Kombination mit einem Command-Pattern, als Kernelement des Technical Designs vor, aber die sind natürlich auch ein wichtiger Punkt für die Entkopplung zwischen verschiedenen Kontexten, da kommt man dann auch wieder ins Strategic Design. Das Domain Event kann einerseits verwendet werden für die interne Persistierung, da kommen wir dann in die Richtung Event Sourcing, CQRS etc., worauf wir heute nicht eingehen wollen. Aber die kann ich auch verwenden als Transportvehikel über ein Messaging-System, beispielsweise Kafka oder so etwas, um quasi sehr entkoppelt, reagierend mit anderen Kontexten kommunizieren zu können.

Lucas Dohmen: Eine Sache, in der man auch häufig von Domain-driven Design hört, sind Microservices. Das scheint sich ja irgendwie gegenseitig zu befruchten. Du bist darauf eben schon kurz eingegangen, magst du da noch mal kurz sagen, wo du da die Zusammenhänge siehst und wo du vielleicht die Stärken siehst, wie man beide Sachen kombiniert?

Michael Plöd: Ja, gerne. Ich würde mal sagen, im Laufe der Zeit hat sich der Fokus von Domain-driven Design auch ein bisschen verändert. Früher hat man eigentlich ganz stark Internal Building Blocks diskutiert, also das Technical Design, Entities, Aggregates etc. Mit dem Aufkommen von Microservices, hat sich der Domain-driven Design-Fokus ein bisschen verändert, und zwar in meinen Augen ganz stark in Richtung auf Konstrukte wie den Bounded Context, und es stellt sich ja immer wieder die Frage, wie groß oder vor allem wie klein, wie Micro soll denn so ein Service sein, den ich da bauen will? Was man in der Microservice-Literatur in etwa genauso häufig liest, wie Referenzen auf Conway’s Law, ist die Aussage, „schneidet eure Microservices entlang von Bounded Context.“ Also, die Idee und auch das konzeptionelle Modell von dem Bounded Context passt halt wie die Faust aufs Auge auf die Idee von Microservices.

Ich würde die Aussage allerdings gerne ein bisschen modifizieren. Ich weiß nicht mehr, wo ich das mal gelesen oder gehört habe, aber das ist etwas, wo ich sage, dem stimme ich vorbehaltlos zu. Ich würde die Aussage gerne dahingehend modifizieren, ich würde einen Microservice minimal so klein schneiden, wie ein Aggregate mit einem zugehörigen Application Service vielleicht und einem Repository, und maximal so groß schneiden wie einen Bounded Context. Ich bin immer kein Freund von Schwarz-Weiß-Betrachtungen, so fundamentalistischen “Nur-So”-Aussagen, sondern ich sage immer, die Welt hat Grauschattierungen, die hat Schattierungen, die hat Farbtöne und ich finde, das ist so eine Range, die eigentlich ganz gut passt auf diese Microservices-Idee.

Weiterhin muss man natürlich sagen, dass das Technical Design ein paar ganz gute Ideen liefert zu der internen Ausgestaltung von Microservices und die Domain Events, die ich gerade erwähnt habe, sind natürlich auch ein sehr gutes Medium, um quasi asynchrone Microservice-Landschaften zu konsumieren. Das heißt, Event-basiert, Message-basiert, also Event-getriebene Architekturen passen eigentlich ganz gut zu der Microservices-Idee, dass ich hinweggehe von ganz stark orchestrierten Microservice-Landschaften mit vielen synchronen Aufrufen von REST-Ressourcen hin zu eher, ich nenne es reagierenden, auf Ereignisse reagierenden Microservice-Landschaften eben auf Domain Events, quasi aufbauen. Von daher passt es ganz gut zusammen und auch die Context Map ist für mich eigentlich ein ganz guter Ausgangspunkt gerade für viele Unternehmen, die eine gewachsene IT-Landschaft haben. Die wenigsten bauen ja auf der grünen Wiese auf. Die meisten haben einfach Legacy an der Backe oder gewachsene Landschaften und da finde ich, dass diese Idee des Context Mappings ein ganz guter Startpunkt ist, um mal zu überlegen, wie will ich das Thema Microservices eigentlich überhaupt angehen?

Lucas Dohmen: Ein Thema, das man bei Microservices ja auch immer wieder hat, sind ja irgendwie Transaktionen zwischen Microservices, die ja sehr schwierig sind. Gibt uns da Domain-driven Design auch eine Antwort, wie wir damit besser umgehen?

Michael Plöd: Nein, eigentlich überhaupt nicht. Das ist etwas, wo Domain-driven Design auch sagt, zwischen Bounded Context: Ich möchte keine kontextübergreifende Transaktion, das ist ganz klar, ich möchte ja nicht einmal eine Aggregat-übergreifende Transaktion. Also Domain-driven Design selbst erwähnt das Wort Microservices eigentlich nicht explizit. Es ist eher, dass die Microservice-Community auf Domain-driven Design schielt und sagt: Hey, das sind ein paar ganz coole Muster drin, da sind ein paar ganz gute Herangehensweisen drin, lasst uns doch das adaptieren, um bessere Microservice-Landschaften zu bauen. Aber ich würde mal sagen, was man rausziehen kann, ist, es sollte keine kontextübergreifende Transaktionen geben.

Lucas Dohmen: Okay. Du hattest auch schon mehrfach jetzt erwähnt, dass es irgendwie einen Ursprung davon gibt. Kannst du uns vielleicht ein bisschen was zu Büchern sagen? Gibt es da Bücher, die man unbedingt gelesen haben sollte oder andere Materialien, wie Talks, die man vielleicht gesehen haben sollte?

Michael Plöd: Ich sage mal so: Das Ursprungsbuch und das Hauptbuch zu Domain-driven Design heißt “Domain-driven Design”. Man nennt es in der Domain-driven Design-Community auch das “blue book”, das blaue Buch. Es wurde geschrieben von Eric Evans, ist 2003 herausgekommen, glaube ich, und das hat eigentlich den ganzen Stein ins Rollen gebracht. Ich würde sagen, viel IT-Literatur ist tendenziell sehr vergänglich. Es gibt Bücher, die liest man halt, die haben irgendwie eine Aktualität von ein, zwei Jahren und danach sind die irgendwie veraltet oder nicht mehr so relevant. Ich würde sagen, Domain-driven Design kam im Jahr 2003 raus, wir sitzen jetzt im Jahr 2017 zusammen und das Thema ist eigentlich relevanter denn je. Das gehört für mich so zu den ewigen Klassikern der IT-Literatur. Das ist jetzt nicht ein ganz leicht zu konsumierendes Buch, aber es enthält trotzdem sehr viele schlaue Ideen, würde ich sagen.

Die modernere Variante davon - und da sieht man auch, dass Domain-driven Design etwas ist, was so ein Konstrukt ist, das einfach im Fluss ist, im Laufe der Zeit - ist dann “Implementing Domain-driven Design” von Vaughn Vernon, das sogenannte “red book”. Das ist beim gleichen Verlag herausgekommen, ist in etwa genauso dick wie das originale Domain-driven Design-Buch, aber es hat ein bisschen einen moderneren Touch. Also, das “Implementing Domain-driven Design” setzt auch ganz stark auf durchaus auf einen Implementierungs-Fokus und auch auf Domain Events, Event Sourcing, CQRS usw. Das wird dort alles diskutiert. Und von dem Buch gibt es noch eine kleinere Variante: “Domain-driven Design Distilled” auch von Vaughn Vernon rausgebracht, auf englisch. Das sind so ca. 100–120 Seiten. Wer da einen einfachen Einstieg will, dem kann ich das empfehlen. Und das Schöne ist, von dem Buch gibt es jetzt auch eine deutsche Fassung. Die ist ganz toll geworden, übersetzt worden von der Carola Lilienthal und dem Henning Schwentner und die ist beim dpunkt Verlag herausgekommen. Da kann man reinschauen und - shameless plug an der Stelle - ich bin momentan auch dran, ein Domain-driven Design-Buch zu schreiben, auf englisch, welches allerdings kein Lehrbuch sein wird, sondern ein Lernbuch. Und zwar startet diese Buch mit einer sehr ausführlichen Fallstudie und anhand der Fallstudie, die 30 bis 40 Seiten in dem Buch einnehmen wird, werde ich quasi sehr, sehr konkret anhand von verschiedenen Beispielen Gedankengänge zur Modellierung von verschiedenen Aspekten mit Domain-driven Design betrachten. Und das ist halt nicht immer nur so: Ihr müsst es so machen, sondern ich werde auch ganz viele Erwägungen einbeziehen: Das wäre folgende Idee, man könnte es so machen. Und ich werde das inkrementell veröffentlichen, auf Leanpub, es nennt sich “Hands-on Domain-driven Design by example” und wird, wie gesagt, auf Leanpub herauskommen, erstes Release wird wahrscheinlich Oktober, November sein.

Lucas Dohmen: Super. Also da packen wir natürlich auch Links in die Shownotes. Eine Frage noch zu den beiden Büchern von Vernon: Wenn man jetzt das “Red Book” liest, also liest das umfangreicher Buch, dann braucht man das “Distilled” nicht mehr zu lesen, weil da alles drinsteht oder ergänzen die sich in irgendeiner Art?

Michael Plöd: Ich würde jetzt sagen, wer das “Red Book” gelesen hat, für den ist das “Distilled” vielleicht einfach noch mal eine knappere Zusammenfassung, eine knappere Referenz. Aber die sind eigentlich inhaltlich in etwa deckungsgleich.

Lucas Dohmen: Okay, super. Dann danke ich dir für das Gespräch. Und den Hörern: Bis zur nächsten Folge vom innoQ-Podcast.

Michael Plöd: Alles klar. Danke, viel Spaß beim Zuhören.

Lucas Dohmen, Michael Plöd: Ciao.