Frage

Ein Teil von Domain-Driven Design, das es nicht viele Details über zu sein scheint, ist, wie und warum Sie Ihren Domain-Modell von Ihrer Schnittstelle isolieren sollte. Ich versuche, meine Kollegen davon zu überzeugen, dass dies eine gute Praxis ist, aber ich scheine nicht viel Fortschritte zu machen ...

Sie nutzen Domain-Entitäten, wo immer sie in der Präsentation und Zwischenschichten bitte. Als ich ihnen argumentieren, dass sie sollten Display-Modellen oder DTOs werden unter Verwendung der Domain-Schicht von der Grenzschicht zu isolieren, begegnen sie, dass sie den Geschäftswert dabei so etwas nicht sehen, weil Sie jetzt ein UI-Objekt haben zu halten sowie das ursprüngliche Domain-Objekt.

Also für einige konkrete Gründe, warum ich suche ich diese sichern können. Im Einzelnen:

  1. Warum sollten wir nicht Domänenobjekte in unserer Präsentationsschicht verwenden?
    (Wenn die Antwort die offensichtlichste ist, ‚Entkopplung‘, dann bitte erklären, warum dies in diesem Zusammenhang wichtig ist)
  2. Sollten wir weitere Objekte oder Konstrukte unsere Domain-Objekte von der Schnittstelle zu isolieren?
War es hilfreich?

Lösung

Ganz einfach, ist der Grund, eine der Implementierung und Drift. Ja, Ihre Präsentationsschicht muss wissen, über Ihre Business-Objekte, um sie richtig zu repräsentieren. Ja, am Anfang sieht es aus wie es viele Überschneidungen zwischen der Umsetzung der beiden Arten von Objekten ist. Das Problem ist, wie die Zeit vergeht, werden die Dinge auf beiden Seiten hinzugefügt. Präsentation Änderungen und die Bedürfnisse der Präsentationsschicht evolve enthalten Dinge, die völlig unabhängig von Ihrer Business-Schicht (Farbe, zum Beispiel) sind. Inzwischen, ändern Sie Ihre Domain-Objekte im Laufe der Zeit, und wenn Sie entsprechende Entkopplung nicht von Ihrer Schnittstelle haben, laufen Sie Gefahr, Verschrauben, indem sie scheinbar gutartige Veränderungen an Ihren Business-Objekten Ihre Grenzschicht auf.

Ich persönlich glaube, der beste Weg, Dinge zu nähern das streng durchgesetzt Schnittstelle Paradigma ist durch; das heißt, setzt Ihr Unternehmen Objektschicht eine Schnittstelle, die die einzige Möglichkeit ist, dass es mit kommuniziert werden kann; keine Implementierungsdetails (das heißt Domain-Objekte) über die Schnittstelle freigelegt werden. Ja, das bedeutet, dass Sie Ihre Domain-Objekte in zwei Standorten implementieren müssen; Ihre Grenzschicht und in der BO-Schicht. Aber das Neuimplementierung, während es zunächst wie zusätzliche Arbeit zu sein scheint, hilft die Entkopplung zu erzwingen, die viel Arbeit zu einem bestimmten Zeitpunkt in der Zukunft retten wird.

Andere Tipps

Ich habe mit diesem selbst zu kämpfen. Es gibt Fälle, in denen ein DTO Sinn in presentaton zu bedienen ist. Lassen Sie uns sagen, dass ich ein Drop-Down der Unternehmen in meinem System zeigen wollen, und ich brauche ihre ID den Wert zu binden.

Nun, anstatt eine CompanyObject des Ladens, die Verweise auf Abonnements haben könnte oder wer weiß was sonst, ich könnte ein DTO mit dem Namen und der ID zurückschicken. Dies ist eine gute Verwendung IMHO.

Sie nun ein weiteres Beispiel. Ich habe ein Objekt, das eine Schätzung darstellt, könnte diese Schätzung auf Arbeit gemacht werden, Ausrüstung usw., es könnte viele Berechnungen, die vom Benutzer definiert werden, die diese Elemente alle nehmen und summieren sie auf (Jede Schätzung könnte mit verschiedenen Arten unterschiedlich sein von Berechnungen). Warum sollte ich zweimal dieses Objekt zu modellieren haben? Warum kann ich nicht einfach meine UI über die Berechnungen aufzuzählen haben und sie angezeigt werden?

Ich benutze keine DTO im Allgemeinen meiner Domäne Schicht aus meiner UI zu isolieren. Ich sie tun verwenden, um meine Domain-Schicht von einer Grenze zu isolieren, die außerhalb meiner Kontrolle. Die Idee, dass jemand Navigationsinformationen setzen würde in ihrem Business-Objekt ist lächerlich, nicht kontaminiert Ihr Business-Objekt.

Die Idee, dass jemand der Validierung in ihrem Business-Objekt setzen würde? Nun, ich sagen, dass dies eine gute Sache. Ihre UI sollte nicht die alleinige Verantwortung Ihre Business-Objekte zu validieren. Ihre Business-Schicht muss tun, um seine eigene Validierung.

Warum werden Sie UI Generation Code in einem busienss Objekt setzen? In meinem Fall habe ich separate Objekte, die das UI-Code über Einzel von der Benutzeroberfläche erzeugt. Ich habe sperate Objekte, die meine Geschäftsobjekte in XML machen, die Idee, dass Sie Ihre Schichten trennen müssen diese Art von Verunreinigung zu verhindern mir so fremd ist, weil warum sollte man auch HTML-Generierung Code in einem Business-Objekt setzen ...

Bearbeiten Da ich ein bisschen mehr denken, gibt es Fälle, in denen UI Informationen in der Domänenschicht gehören könnten. Und dies könnte Wolke, was man eine Domain-Ebene nennen, aber ich arbeitete an einer Multi-Tenant-Anwendung, die sehr unterschiedliches Verhalten sowohl UI Aussehen hatte und fühlen und funktionalen Workflow. In Abhängigkeit von verschiedenen Faktoren ab. In diesem Fall hatten wir ein Domain-Modell, das die Mieter und deren Konfiguration dargestellt. Ihre Konfiguration passierte UI-Informationen (Aufkleber für generische Felder zum Beispiel) umfassen.

Wenn ich meine Objekte zu entwerfen, um sie persistierbar zu machen, sollte ich auch die Objekte duplizieren? Denken Sie daran, wenn Sie jetzt ein neues Feld hinzufügen möchten, Sie haben zwei Orte, um es hinzuzufügen. Vielleicht stellt sich eine andere Frage, ob Ihre DDD verwenden, sind alle Einheiten Domain-Objekte beibehalten? Ich weiß in meinem Beispiel sie waren.

Sie tun es aus dem gleichen Grund Sie SQL halten aus Ihrem ASP / JSP-Seiten.

Wenn Sie nur ein Domain-Objekt zu halten, für die Verwendung in der Präsentation und Domain-Schicht, dann ist das ein Objekt bald monolithisch bekommt. Es beginnt UI Validierungscode, UI Navigationscode und UI Generation Code enthalten. Dann fügen Sie bald alle der Business-Schicht Methoden obendrein. Jetzt ist Ihre Business-Schicht und UI sind alle durcheinander, und alle von ihnen sind auf der Domäne-Einheit Schicht rumgespielt.

Sie wollen, dass raffinierten UI-Widget in einer anderen App wieder zu verwenden? Nun, Sie haben eine Datenbank mit diesem Namen zu erstellen, diese beiden Schemata und diese 18 Tabellen. Sie müssen auch Hibernate und Spring (oder Ihre Rahmen der Wahl) konfigurieren, dass die Business-Validierung zu tun. Oh, müssen Sie auch diese 85 andere nicht verwandten Klassen, weil sie in der Business-Schicht Bezug genommen werden, die gerade in der gleichen Datei sein geschieht.

ich nicht zustimmen.

Ich denke, der beste Weg zu gehen ist mit Domain-Objekten in Ihrer Präsentationsschicht zu beginnen, bis es Sinn macht, es anders zu machen.

Im Gegensatz zur landläufigen Meinung, „Domain-Objekte“ und „Value-Objekte“ kann glücklich koexistieren in der Präsentationsschicht. Und dies ist der beste Weg, es zu tun - Sie den Nutzen aus beiden Welten, reduzierte Verdoppelung (und Standardcode) mit den Domänenobjekten; und die Schneiderei und konzeptionelle Vereinfachung der Wertobjekte über Anfragen verwendet wird.

Wir sind mit dem gleichen Modell in dem Server und auf dem ui. Und es ist ein Schmerz. Wir haben es einen Tag Refactoring.

Die Probleme sind vor allem, weil das Domain-Modell in kleinere Stücke geschnitten werden muss in der Lage sein, es zu serialisieren ohne referenzierte die gesamte Datenbank mit. Dies macht es schwieriger auf dem Server zu verwenden. Wichtige Links fehlen. Einige Arten sind auch nicht serialisierbar und kann nicht an den Client gesendet werden. Zum Beispiel ‚Typ‘ oder jede generischen Klasse. Sie müssen in der nicht-generic und Typ muss als Zeichenfolge übertragen werden. Dies erzeugt zusätzliche Eigenschaften für die Serialisierung, sie sind überflüssig und verwirrend.

Ein weiteres Problem ist, dass die Einheiten auf der Benutzeroberfläche nicht wirklich fit. Wir sind mit Datenbindung und viele Unternehmen haben viele redundante Eigenschaften nur für ui Zwecke. Zusätzlich gibt es viele ‚BrowsableAttribute‘ und andere in der Entity-Modell. Das ist wirklich schlecht.

Am Ende, ich denke, es ist nur eine Frage von welcher Art und Weise einfacher ist. Es könnte von Projekten, bei denen es funktioniert gut und wo es keine Notwendigkeit, ein anderes DTO Modell schreiben zu können.

Antwort hängt von Umfang Ihrer Anwendung.


Einfache CRUD (Create, Read, Update, Delete) Anwendung

Für grundlegende crud Anwendungen, die Sie haben keine Funktionalität. Hinzufügen von DTO auf den Entitäten woudl eine Verschwendung von Zeit. Es würde die Komplexität erhöhen, ohne die Skalierbarkeit zu erhöhen.


Mäßig kompliziert Nicht CRUD Anwendung

In dieser Größe Anwendung werden Sie wenige Einheiten haben, die wahre lifeclycle und einige Business-Logik haben mit ihnen verbunden sind.

Hinzufügen DTOs zu diesem Fall ist eine gute Idee für ein paar Gründe:

  • Präsentationsschicht kann nur Teilmenge von Feldern sehen, die Einheit hat. Sie kapseln Entities
  • Keine Kopplung zwischen Backend und Frontend
  • Wenn Sie Geschäftsmethoden innerhalb Entitäten haben, aber nicht in DTO dann DTOs Hinzufügen bedeutet, dass außerhalb Code nicht Zustand Ihres Unternehmens ruinieren kann.


Komplizierte Enterprise Application

Einheit möglicherweise mehr Möglichkeiten der Präsentation benötigen. Jeder von ihnen müssen andere Reihe von Feldern. In diesem Fall treten die gleichen Probleme wie in den vorangegangenen Beispiel plus benötigen Menge von Feldern für jeden Kunden sichtbar zu steuern. getrennten DTO Mit Ihnen helfen, für jeden Kunden zu bieten, was sichtbar sein soll.

Es geht um Abhängigkeiten für den größten Teil. Der Kern funktionale Struktur der Organisation hat ihre eigenen funktionalen Anforderungen und die UI sollten die Menschen um den Kern zu ändern aktivieren und anzuzeigen; aber der Kern selbst sollte nicht erforderlich, um die Benutzeroberfläche anzupassen. (Wenn es geschehen muss, ist es in der Regel ein Hinweis der Kern nicht Eigentum ausgelegt ist.)

Mein Abrechnungssystem hat eine Struktur und Inhalt (und Daten), die angeblich den Betrieb meines Unternehmens zu modellieren. Diese Struktur ist real und existiert unabhängig davon, welche Abrechnungssoftware ich verwende. (Zwangsläufig ein bestimmtes Softwarepaket enthält Struktur und Inhalt um ihrer selbst willen, sondern ein Teil der Herausforderung diesen Aufwand wird minimiert wird.)

Im Grunde eine Person einen Job zu erledigen. Die DDD sollte den Ablauf und die Inhalte des Auftrags entspricht. DDD geht es darum, explizit alle Jobs, die Anzeige vollständig und unabhängig wie möglich erfolgen müssen wird. Dann hoffentlich die Benutzeroberfläche erleichtert die Arbeit zu erledigen, so transparent wie möglich, so produktiv wie möglich.

Schnittstellen ist über die Ein- und Ansichten für den richtig modellierte und unveränderlichen Funktionskern zur Verfügung gestellt.

Dammit, I schwören das sagte Ausdauer.

Wie auch immer, es ist eine weitere Instanz derselben Sache: Parnas Gesetz sagt ein Modul ein Geheimnis bewahren sollte, und das Geheimnis ist eine Anforderung, die sich ändern können. (Bob Martin hat eine Regel, die eine andere Version davon ist.) In einem System wie dieses, die Präsentation kann unabhängig von der ändern Domain . Wie zum Beispiel ein Unternehmen, das Preise in Euro und nutzt Französisch in den Firmenbüros, sondern will präsentieren Preise in US-Dollar mit Text in Mandarin hält. Die Domäne ist die gleiche; die Präsentation kann sich ändern. Also, die Brüchigkeit des Systems zu minimieren - das heißt, die Anzahl der Dinge, die geändert werden müssen, um eine Änderung in den Anforderungen zu implementieren - trennen Sie die Bedenken

.

Ihre Präsentation kann Hinweis Ihre Domain Schicht, aber es sollte von Ihrem ui auf Ihre Domain-Objekte keine Bindung direkt sein. Domain-Objekte sind nicht für die UI-Nutzung gedacht, da sie häufig sind, wenn sie richtig ausgelegt, auf Basis Verhalten und nicht die Datendarstellungen. Es sollte eine Abbildungsebene zwischen der Benutzeroberfläche und der Domäne sein. MVVM oder MVP, ist ein gutes Muster für diese. Wenn Sie versuchen, direkt die Benutzeroberfläche an die Domäne zu binden, werden Sie via Modem eine Menge Kopfschmerzen für sich selbst erstellen. Sie haben zwei verschiedene Zwecke.

Vielleicht Konzeptualisierung Sie die UI-Ebene in breit genug Bedingungen. Denken Sie an mehrere Formen der Reaktion (Webseiten, Sprachantwort, gedruckte Buchstaben usw.) und in Bezug auf die verschiedenen Sprachen (Englisch, Französisch, etc.).

Nehmen sich nun an, dass der Sprach-Engine für den Telefonanruf-in-System läuft auf eine ganz andere Art von Computer (Mac zum Beispiel) aus dem Computer, der die Website (Windows vielleicht) ausgeführt wird.

Natürlich ist es leicht, in die Falle fallen „Nun, in meiner Firma wir kümmern sich nur um Englisch, laufen unsere Website auf LAMP (Linux, Apache, MySQL und PHP) und jeder benutzt die gleiche Version von Firefox“. Aber was ist in 5 oder 10 Jahren?

Siehe auch den Abschnitt „Datenausbreitung zwischen den Schichten“ in den folgenden, die ich denke, präsentiert überzeugende Argumente:

http: // Galaxie .andromda.org / docs / AndroMDA-Dokumentation / AndroMDA-getting-started-java / java / index.html

Mit Hilfe von Tools wie ‚ Wert Injecter ‘ und das Konzept der ‚Mapper‘ in der Präsentationsschicht während mit Blick arbeitet, ist es viel einfacher, jedes Stück Code zu verstehen. Wenn Sie ein wenig Code haben, werden Sie nicht die Vorteile sofort sehen, aber wenn Ihr Projekt wird mehr und mehr wächst, werden Sie sehr glücklich, während mit den Ansichten arbeiten müssen nicht in die Logik der Dienste geben, Repositorys die Ansicht Modell zu verstehen. Ansicht Modell ist eine weitere Wache in der weiten Welt der Anti-Korruptions-Schicht und wert sein Gewichts in Gold in einem langfristigen Projekt.

Der einzige Grund, warum ich sehe kein Vorteil Ansicht Modell ist, wenn Ihr Projekt klein und einfach ist genug Blick direkt auf jede Eigenschaft des Modells binded haben. Aber wenn in der futur, die Anforderung ändern und einige Steuerelemente in den Ansichten nicht zum Modell binded werden und Sie kein View-Modell Konzept haben, werden Sie Patches beginnen in vielen Orten das Hinzufügen und Sie werden beginnen, einen Legacy-Code zu haben, dass Sie werden nicht zu schätzen wissen. Sicher, können Sie einige Refactoring tun, um Ihr Viewmodel in View-Viewmodel zu transformieren und dem YAGNI Prinzip zu folgen, während nicht-Code hinzufügen, wenn Sie es nicht brauchen, aber für mich, es ist viel mehr eine bewährte Methode, die ich folgen muß hinzufügen Präsentationsschicht ausgesetzt wird nur ansichtsModellObjekte.

Hier ist ein echtes Beispiel dafür, warum ich es gute Praxis separate Domäne Entitäten aus der Sicht finden.

Vor ein paar Monaten habe ich eine einfache Benutzeroberfläche, die Werte von Stickstoff, Phosphor und Kalium in einer Bodenprobe durch eine Reihe von 3 Stärken zu zeigen. Jedes Messgerät hatte einen roten, grünen und roten Bereich, das heißt Sie können entweder zu wenig oder zu viel von jeder Komponente, aber es war eine sichere grüne Ebene in der Mitte.

Ohne viel Gedanken, modellierte ich meine Business-Logik Daten für diese drei chemischen Komponenten und einem separaten Datenblatt zu liefern, die Daten enthalten, über die angenommenen Niveaus in jedem der drei Fälle (einschließlich der Messeinheit verwendet wurde, dh Mol oder Prozentsatz). Ich meine UI dann ein ganz anderes Modell verwenden modelliert wurde dieses Modell besorgt über Spur Etiketten, Werte, Grenzwerte und Farben.

Das bedeutete, als ich 12 Komponenten zeigen musste später, ich kartiert nur die zusätzlichen Daten in 12 neue Spur Ansicht Modelle und sie erschien auf dem Bildschirm. Es bedeutet auch leicht die Spursteuerung wieder verwenden könnte ich und habe sie anderen Datensätze angezeigt werden.

Wenn ich diese Lehren gekoppelt hatte würde direkt in meine Domain Einheiten, würde ich nicht eine der oben genannten Flexibilität und künftiger Änderungen Kopfschmerzen wären. Ich habe über sehr ähnliche Probleme kommen, wenn Kalenders in der UI-Modellierung. Wenn es eine Anforderung für einen Kalendertermin ist rot werden, wenn es 10+ Teilnehmer sind, dann ist die Business-Logik zu handhaben dies in der Business-Schicht bleiben soll und alle Kalender in der Benutzeroberfläche wissen muss, ist, dass sie instruiert wurde röten, sollte es nicht müssen wissen, warum.

Die einzige vernünftige Grund für das Hinzufügen zusätzlicher Zuordnung zwischen verallgemeinert und domänenspezifische Semantik ist, dass Sie (Zugang zu) eine bestehende Stelle des Codes (und Tools), die auf einem generali (aber mappable) Semantik unterscheiden sich von Ihrer Domain Semantik basieren .

Domain Driven Designs funktionieren am besten, wenn sie in Verbindung mit einem orthogonalen Satz von funktionalem Domain-Frameworks (wie ORM, GUI, Workflow etc.) verwendet. Denken Sie immer daran, dass es nur in der äußeren Schicht adjacencies ist, dass Domain-Semantik müssen ausgesetzt werden. Typischerweise ist dies das vordere Ende (GUI) und persistent Back-End (RDBM, ORM). Jegliche effektiv gestaltet Zwischenschichten können und sollten Domain-invariant sein.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top