2009-09-25 12 views
16

Sagen wir, ich habe 2 Einheiten - Foo und Bar. Foo ist ein Aggregatstamm und enthält Bar. Soweit ich verstehe, sollte es so aussehen:DDD: Aggregat Wurzel Frage

public class Foo{ 
    private readonly Bar Bar; 
} 

I Funktionalität zur Verfügung stellen möchten für Benutzer Bars für Foos aus einer definierten Liste zu wählen (und ändern).

Wenn Repositories nur für Aggregat-Roots verwendet werden sollen, bedeutet dies, dass es kein Repository für die Bar-Entität gibt.

Dies führt zu einem Problem - Bar kann nicht unabhängig erstellt/aktualisiert werden, ohne einen Verweis auf Foo.

Bedeutet das, dass Bar ein Repository haben soll, obwohl es ohne Foo keine Bedeutung hat?

+0

Keine so etwas wie eine dumme Frage, nur dumme Antworten;) BTW diese Frage hat mir sehr geholfen – Eldar

Antwort

16

Wenn Sie aus einer Liste von Bars auswählen möchten, in denen sie nicht mit Foo verknüpft sind, ist dies kein Aggregatstamm. Sie können beispielsweise keine OrderItems ohne ihre Order abrufen, daher handelt es sich um einen einzelnen Aggregatstamm (Order). Sie können jedoch eine Liste mit Produkten abrufen, die OrderItems zugewiesen werden, sodass Product nicht Teil des Order-Aggregatstamms ist.

Beachten Sie, dass OrderItem zwar Teil des Order-Aggregatstamms ist, Sie es jedoch unabhängig voneinander erstellen und aktualisieren können. Aber Sie können es nicht ohne Bezug auf Bestellung bekommen. Das gleiche für deine Bar, selbst wenn es Teil von Foo war, könntest du jede (Foo.Bars) bekommen und damit arbeiten oder Foo.AddBar (neue Bar()). Aber wenn Sie List ohne Foo brauchen, ist Bar nicht Teil von Foo Aggregat. Es ist eine separate Einheit.

Nun, so sehe ich DDD hier, aber ich bin natürlich nicht Eric Evans.

+0

Dies ist sinnvoll. Wenn du noch etwas zu sagen hast - mach weiter. :) –

+0

Die Sache, die ich gelernt habe - es gibt zu viele Aggregatwurzeln in meiner Domäne. Es gibt Entitäten, die als Roots erstellt wurden, obwohl sie nicht unabhängig voneinander aktualisiert werden sollten. Noch schlimmer - einige Wurzeln können als Wertobjekte ersetzt werden. –

+1

Ein weiterer Vorschlag, der mir in den Sinn kommt, ist, dass wenn Ihr Bar ein eigenständiges (kann als separate Liste dargestellt werden) und abhängig (arbeitet innerhalb von Foo) zur gleichen Zeit - vielleicht haben Sie tatsächlich zwei Entitäten hier. Ein kurzes Beispiel: Group {Name, Price} - sollte sowohl in Order/Product als auch separat aufgeführt sein, aber wenn Sie es in Group {Name} und ProductGroup {Group, Price} aufteilen, präsentieren Sie Group separat, während ProductGroup als Teil beibehalten wird von Aggregat. – queen3

2

Sind Sie sicher, dass Bar eine Entität sein muss? Müssen Sie es verfolgen und in der Domain ändern? Wenn Sie es als Wertobjekt betrachten können, würde ich vorschlagen, dass Sie es von einem Dienst abrufen und dann das ausgewählte Wertobjekt mit der Foo-Entität "verbinden". Für Augenblicke durch eine Dropdown-Liste.

+0

Und warum Entität kann nicht sein durch Service abgeholt und mit Foo verbunden? –

+0

Wie Wertobjekte erstellt/aktualisiert werden sollen ohne Kontext der Entität? Wäre das nicht ein Maskierungsdienst als Repository, welches Wertobjekt nicht haben sollte? –

+0

Lassen Sie mich erklären, wie ich das gemacht habe; Ich brauche einen Weg, um Daten von der persistenten Schicht zu bekommen. Ich könnte ein DTO verwenden, um die Daten abzurufen, aber ich benutze lieber ein Wertobjekt, weil ich dann das Objekt in der Domäne verwenden kann, ohne vom DTO zum Wertobjekt zu mappen. Das Objekt, das ich verwende, ist eine Klasse aus dem aggregierten Stamm, in diesem Fall Bar. Wenn ich dies für eine Entität tun würde, würde ich wahrscheinlich ein DTO verwenden (über einen Service abgerufen), um die Liste (Combobox usw.) zu füllen, und wenn ich den richtigen Balken ausgewählt habe, würde ich das Repository bitten, mir das komplette Objekt zu beschaffen aus der aggregierten Wurzel. Hoffe, das macht Sinn. – Fossmo

8

Die Gründe für die Aggregate Wurzeln haben, sind:

  1. Sie kontrollierten bieten und Gesteuerter Zugriff auf zusammengesetzte Entitäten
  2. Sie Regeln durchsetzen können, um sicherzustellen, dass das gesamte Aggregat

gültig ist mein take: Wenn Sie Bar Objekte ohne Foo auswählen müssen, verwenden Sie BarRepository.

Aber ... Was ist, wenn Sie ein Bar aktualisieren, und es bricht eine Gültigkeitsregel für seine Eltern Foo? Wenn dies passieren könnte, sollten Sie Bar über seine Eltern Foo zugreifen.

Wenn jedoch benötigen Sie eine Reihe von Bar Objekte zuzugreifen (z für einen Batch-Job oder einen Bericht), und Sie wissen dass Foos nicht kaputt gehen, gehen Sie vor und greifen Sie über BarRepository.

Denken Sie daran, dass Aggregatwurzeln aus anderen Aggregatwurzeln bestehen können.Sie können feststellen, dass Bar ist ein Aggregat root selbst, geben Sie eine Begründung für eine BarRepository :)