Dies ist der Beginn einer Serie zum Thema Domain Driven Design (DDD). Ich werde versuchen, die Serie mit weiteren Beiträgen zu füllen, während ich an einem Vortrag zum Thema arbeite.
Domain Driven Design ist der Titel eines Buches von Eric Evans. Das Buch selbst ist nicht mehr “ganz neu” – trotzdem gab es (gerade auch in den Java und ALT.NET Gemeinschaften) einigen “Hype” darum. Dabei gibt es eigentlich nicht genau das DDD. Zunächst ist DDD eine Kombination aus “Model Driven Design” (nicht zu verwechseln mit MDA – Model Driven Architecture) und Prozessen rund um Kunden-Kommunikation, Integration und Modularisierung verschiedener Domänen, etc..
Nun stellt sich natürlich die Frage, wann DDD eingesetzt werden sollte. Zunächst ist die Ansatz der allgegenwärtigen Sprache sicherlich universell nutzbar. Um den vollen Nutzen zu erfahren ist aber sicherlich die Kopplung mit Model Driven Design empfehlenswert. Ausgangspunkt ist das Domain Model Pattern von Martin Fowler. Hierbei sollen die kompletten Fähigkeiten unserer OOP-Sprachen genutzt werden, um die Komplexität der Domäne in ein reichhaltiges Objektmodell zu übersetzten.
Damit dürfte klar sein, dass Model Driven Design, also OO-Modelle der Domäne, sich vor allem in OLTP-Szenarios einsetzten lassen. Derzeit ist Objekt-Orientierung einer der stärksten Ansätze, die wir kennen, um hohe Modularisierung und Reduzierung der Komplexität zu erreichen.
Dies bedeutet aber auch, dass OLAP-Szenarios ungeeignet für den Einsatz eines reichhaltigen Objektmodells sind – denn hierbei geht es primär um die Analyse von Daten und weniger um komplexe Prozesse und Regeln innerhalb von Transaktionen. Die Frage nach Ad-hoc Reporting wurde auf der DDD-Mailingliste schon mehrfach gestellt und auch beantwortet – mittlerweile gibt es dazu auch einen Artikel und eine Diskussions-Zusammenfassung auf der Webseite zu DDD. Ich möchte hier nicht direkt im Detail darauf eingehen - dies werde ich zu einem späteren Zeitpunkt noch tun. Zusammenfassend möchte ich aber sagen, das solche Objektmodelle und damit verbundene Datenbank-Schemata eigentlich nicht zum performanten Ad-hoc Reporting geeignet sind. Alternativen wären flache, spezielle Datenbank-Sichten oder eine Art Data-Warehouse-Lösung.
Ziel des Model Driven Design ist also die Erstellung eines reichhaltigen Objektmodells, das wir mit völliger Freiheit unter Ausnutzung aller Sprach-Features erstellen. Zu starke Kopplung an die Infrastruktur (etwa Basisklassen mit Transaktions- und Datenbank-Logik) sind hier hinderlich. Deshalb ist der Begriff “Persistence Ignorance” eng mit der Erstellung solcher Objektmodelle verbunden. Objekte ohne Einschränkung durch Infrastruktur oder Runtime-Container (wie zB EJB 2.0 - Java , CSLA - dotnet) werden auch POCOs genannt – Plain Old CLR Objects. Ich würde sogar noch ein Stück weiter gehen und von Infrastruktur-Ignoranz sprechen, da Persistenz nur ein Aspekt der Infrastruktur ist.
Natürlich bedeutet dies auch, dass wir gewisse Anforderungen an die Architektur solcher Systeme haben, auf der anderen Seite aber auch eine Menge gewinnen. Zunächst möchte ich auf die Gewinne eingehen. Solche Objektmodelle eigenen sich perfekt um Komplexität zu verstecken und Änderung zu handhaben. Die Arbeit mit solchen Modellen führt zu ausdrucksstarken Kombinationen aus bereits bestehenden ausdrucksstarken Teilen. Damit gewinnen wir als Lesbarkeit und auch Wartbarkeit. Objektmodelle ohne Abhängigkeit von der Infrastruktur bedeuten natürlich auch einfache Testbarkeit. Somit ist es möglich, die gesamte komplexe Logik in Objektmodelle mit automatisierten Tests ständig zu überprüfen. Unsere Architektur wird hier also testbar und wir werden nicht gehindert Tests zu entwickeln oder gar Test-first (TDD) zu arbeiten. Solche Objektmodelle erleichtern die Arbeit mit automatisierten Tests geradezu.
Es gibt aber auch einige Anforderungen an unsere Architekturen, um solche reichhaltigen Objektmodelle im Sinne von DDD zu entwickeln. Diese sind nicht unbedingt negativ (haben sogar positiven Einfluss auf das gesamte System), sind teilweise aber fast Voraussetzung. Zunächst einmal lassen sich Infrastruktur-Ignorante Objektmodelle im Prinzip nur entwickeln, wenn wir das Dependency Inversion Principle anwenden. Dies führt sofort zur Notwendigkeit eines Dependency-Injection-Containers zur Konfiguration der Abhängigkeiten. Natürlich ließe sich das DIP auch anders realisieren, pragmatisch gesehen nehmen uns solche Container (Castle Windsor, Spring.NET, StructureMap, Ninject) aber sehr viel Arbeit ab. Der Einsatz eines solchen IoC/DI-Containers hat darüber hinaus einen positiven Effekt auf die gesamte Anwendung: lose Kopplung ist schließlich eine Eigenschaft, die man sich generell (neben hoher Kohäsion) für seine Module wünscht.
Soll unser Objektmodell persistiert werden, brauchen wir auch einen starken, flexiblen O/R-Mapper. In letzter Zeit gab es viel Rumoren um das Entity Framework – um es kurz zu machen: derzeit sieht sowohl das EF-Team als auch die ALT.NET Community das EF nicht als eine Option an, wenn man DDD nutzt. Derzeit stärkstes Framework auf dem Markt ist damit NHibernate, eine ehemalige Portierung des Java-Frameworks Hibernate. NHibernate ist komplett in das dotnet-Ökosystem integriert und weit verbreitet.
Die Entwicklung reichhaltiger Objektmodelle erfordert zudem generell eine Leistungsfähige Entwickler-Struktur, denn ohne gute, OOP-erfahrene Entwickler ist es schwierig ein reichhaltiges Objektmodell zu erstellen. Viele Entwickler sehen sich zwar als OOP-erfahren, doch ist es noch ein großer Unterschied eine OOP-Sprache wie C# einzusetzen oder aber gute, leistungsfähige Objektmodelle zu entwickeln. Dies merkt eigentlich jeder, der bisher noch nie mit aller Kraft versucht hat, ein Modell noch reichhaltiger zu machen. Die ersten Versuche scheitern wohl in der Regel (und sind es auch bei mir). Das eingestehen und sehen der Fehler ist hier der Schlüssel um sich weiterzuentwickeln. Viele open-source Projekte nutzen reichhaltige Objektmodelle und sind optimal zum Lernen.
Zum Schluss noch einige Worte zum Aufwand. Ein Objektmodell zur Repräsentation der Domäne zu erstellen ist harte Arbeit und aufwendig – dem gegenüber steht aber die Leichtigkeit mit der später Komplexität gehandhabt werden kann (wenn das Modell gut genug ist). Als Alternativen gäbe es noch die Arbeit mit Transaction Scripts (Fowler) oder dem Table Module Pattern (Fowler). Letzteres erfreut sich gerade bei .NET-Entwicklern großer Beliebtheit wegen der guten IDE-Unterstützung in Visual Studio, dort bekannt als DataSets. Für einen genauen Vergleich möchte ich auf Martin Fowler’s Buch “Patterns of Enterprise Application Architecture” verweisen. Es sei aber gesagt, dass gerade das Table Module Pattern wahrscheinlich am wenigsten mit steigender Komplexität der Domäne skaliert, gefolgt von Transaction Scripts. Beide haben vor allem das Problem von Copy&Paste-Smells und Dopplung von Logik. Nach derzeitigem Stand ist ein objekt-orientieres Modell das einzige, das wirklich besser mit wachsender Komplexität skaliert. Problematisch ist allerdings, dass man Komplexität schlecht messen kann und keiner genau weiß, wo die Schwellwerte liegen. Letzten Endes ist hier die Erfahrung und Experimente / Prototypen gefragt.
Tags: ddd, domain driven design, domainmodel, dotnet
Hahaha! Der war gut...
Nein ernsthaft, habe DDD noch nirgends in DE im Einsatz gesehen.
Ich habe zwar keine Daten, aber ich schätze, dass der Anteil von DDD deutlich im Promille-Bereich liegt.
Nichtsdesto trotz muss man sich im klaren sein, das DDD für "richtig komplizierte Anforderungen und Logik" gedacht ist, und sicherlich nicht für die 100mio-ste CRUD-Anwendung die jemand zusammensteckt. Demnach ist das Einsatzgebiet auch wirklich begrenzt.
Zwischen "Jeder" und "ich kenne einige" ist aber doch eine Lücke. ;)
Ansonsten Hut ab! für deinen Mut DDD in deutscher Sprache zu erklären. Mir ist es bisher nicht wirklich gut gelungen.
Ich weiß zwar genau, was das ist, aber es wirklich beschreiben, ohne die Antworten "Häh?" und "Und?" zu erhalten ist doch sehr schwierig.
Dieser Artikel trägt zwar den Titel "Eine Einführung", dennoch gelingt es dir leider nicht die wichtigste Frage: "Was ist DDD?" zu beantworten. IMHO versteht man den Artikel bzw. die Zusammenhänge darin nur, wenn man bereits weiß, was DDD ist.
Ich würde mich freuen über eine kurze und knackige deutschsprachige Formulierung des DDD-Gedanken.
Ansonsten freue ich mich schon auf die nächsten Beiträge dieser Serie.
Ciao,
Jens