Was ist eine aggregierte Wurzel?

447

Ich versuche mir ein Bild davon zu machen, wie man das Repository-Muster richtig verwendet. Das zentrale Konzept einer aggregierten Wurzel taucht immer wieder auf. Wenn ich sowohl im Web als auch im Stapelüberlauf nach Hilfe für einen aggregierten Stamm suche, finde ich immer wieder Diskussionen darüber und tote Links zu Seiten, die Basisdefinitionen enthalten sollen.

Was ist im Kontext des Repository-Musters eine aggregierte Wurzel?

Dinah
quelle
16
Überprüfen Sie die folgenden Fallstudien. Effektives Aggregatdesign Teil I: Modellieren eines einzelnen Aggregats dddcommunity.org/wp-content/uploads/files/pdf_articles/… Teil II: Zusammenarbeiten von Aggregaten dddcommunity.org/wp-content/uploads/files/pdf_articles/… Teil III: Einblicke durch Entdeckung gewinnen dddcommunity.org/wp-content/uploads/files/pdf_articles/…
Ben Vitale

Antworten:

310

Im Kontext des Repository-Musters sind aggregierte Roots die einzigen Objekte, die Ihr Client-Code aus dem Repository lädt.

Das Repository kapselt den Zugriff auf untergeordnete Objekte - aus der Sicht eines Aufrufers werden sie automatisch geladen, entweder gleichzeitig mit dem Laden des Stammverzeichnisses oder wenn sie tatsächlich benötigt werden (wie beim verzögerten Laden).

Beispielsweise könnten Sie ein OrderObjekt haben, das Operationen für mehrere LineItemObjekte kapselt . Ihr Client-Code würde die LineItemObjekte niemals direkt laden, sondern nur die Order, die sie enthalten. Dies wäre der aggregierte Stamm für diesen Teil Ihrer Domain.

Jeff Sternal
quelle
21
Wenn der Client-Code das LineItem für einen anderen Zweck benötigt, würde dies hypothetisch ein separates Aggregat bilden (vorausgesetzt, es handelt sich um andere Objekte, die nicht mit dem Order-Objekt zusammenhängen)?
Ahmad
20
@Ahmad, andere Aggregate bezeichnen LineItems möglicherweise als schreibgeschützte Daten. Sie können sie einfach nicht ändern . Wenn andere Aggregate sie ändern könnten, könnten Sie die Invarianten der Bestellung (noch die Werbebuchungen) nicht schützen.
Jeff Sternal
4
Schauen Sie sich das an, z . B. lostechies.com/blogs/jimmy_bogard/archive/2010/02/23/… . Im Beispiel ist der Kunde eine Invariante der Bestellung, oder? Der Kunde kann jedoch auch die andere aggregierte Wurzel sein? Oder fehlt mir hier ein grundlegendes Verständnis?
Ahmad
3
@ Jeff Du hast gesagt "sie können sie einfach nicht ändern" - ist das durchsetzbar oder eine Frage der Konvention?
Neil Barnwell
4
@Neil: Ich würde es mit allen verfügbaren Sprachmechanismen erzwingen - zum Beispiel indem ich eine unveränderliche Klasse zur Darstellung der Daten erstelle.
Jeff Sternal
206

Von Evans DDD:

Ein AGGREGATE ist ein Cluster zugeordneter Objekte, die wir zum Zweck von Datenänderungen als Einheit behandeln. Jedes AGGREGATE hat eine Wurzel und eine Grenze. Die Grenze definiert, was sich im AGGREGATE befindet. Die Wurzel ist eine einzelne, spezifische ENTITY, die im AGGREGATE enthalten ist.

Und:

Die Wurzel ist das einzige Mitglied des AGGREGATE, das außerhalb von Objekten Verweise auf [.] Enthalten darf.

Dies bedeutet, dass aggregierte Wurzeln die einzigen Objekte sind, die aus einem Repository geladen werden können.

Ein Beispiel ist ein Modell, das eine CustomerEntität und eine AddressEntität enthält. Wir würden niemals Addressdirekt vom Modell aus auf eine Entität zugreifen, da dies ohne den Kontext eines zugeordneten Modells keinen Sinn ergibt Customer. Wir könnten das also sagen Customerund Addresszusammen ein Aggregat bilden und das Customerist eine aggregierte Wurzel.

Jason
quelle
57
Update von Eric Evans : Betonen Sie, dass aggregierte Wurzeln Konsistenzgrenzen für Transaktionen / Parallelität sind, und betonen Sie, dass externe Entitäten keine Verweise auf untergeordnete Entitäten anderer Aggregate enthalten können.
Brian Low
3
Das Wortspiel verwirrt mich also für immer. Each AGGREGATE has a rootund The root is the only *member* of the AGGREGATE- dieses Verb impliziert, dass die Wurzel eine Eigenschaft des Aggregats ist. In allen Beispielen ist es jedoch umgekehrt: Die Wurzel enthält Eigenschaften, die Aggregate sind. Könntest Du das erläutern?
Sinaesthetic
1
Wird die CustomerKlasse als aggregierte Wurzel oder Customer Instanz betrachtet , um meine Sprache richtig zu machen ?
Joe
1
Im Allgemeinen wäre der Kunde im Kunden-Bestell-Einzelposten-Paradigma die aggregierte Wurzel. Die Instanz eines Kunden wäre eine Instanz dieses aggregierten Stamms. Wenn Sie von einem Aggregatstamm namens Kunde sprechen, diskutieren Sie die logische Konstruktion eines Kunden, aus dem die Instanz eines Kunden besteht. Eine Sammlung von Kunden ist nur eine Sammlung.
Ibrahim Malluf
111

Aggregate Root ist ein komplexer Name für eine einfache Idee.


Grund Idee

Gut gestaltetes Klassendiagramm kapselt seine Interna. Der Punkt, über den Sie auf diese Struktur zugreifen, wird aufgerufen aggregate root.

Geben Sie hier die Bildbeschreibung ein

Interna Ihrer Lösung können sehr kompliziert sein, aber Benutzer dieser Hierarchie verwenden nur root.doSomethingWhichHasBusinessMeaning().


Beispiel

Überprüfen Sie diese einfache Klassenhierarchie Geben Sie hier die Bildbeschreibung ein

Wie willst du mit dem Auto fahren? Wählte bessere API

Option A (es funktioniert einfach irgendwie):

car.ride();

Option B (Benutzer hat Zugriff auf Klasseninternale):

if(car.getTires().getUsageLevel()< Car.ACCEPTABLE_TIRE_USAGE)
    for (Wheel w: car:getWheels()){
        w.spin();
    }
}

Wenn Sie der Meinung sind, dass Option A besser ist, dann herzlichen Glückwunsch. Sie bekommen Hauptgrund dahinter aggregate root.


Der aggregierte Stamm kapselt mehrere Klassen. Sie können die gesamte Hierarchie nur über das Hauptobjekt bearbeiten.

Marcin Szymczak
quelle
17
Ich mag das Beispiel, aber ich habe Schwierigkeiten, ein Szenario zu finden, in dem der Kunde auf Engine verweisen sollte. Es scheint, als ob der Motor hinter dem Auto eingekapselt sein sollte. Können Sie das etwas näher erläutern?
Emragins
Meiner Meinung nach muss sich der Motor selbst in einem fahrzeugspezifischen Modell befinden, z. B. einem BMW Series 5 mit 3000-cm3-Motor. Bei dieser Modellierung ist der Motor eine Komponente für ein Auto.
Parama Dharmika
1
@ParamaDharmika sicher, Sie können es so modellieren. Das hängt davon ab, wie „fortgeschritten“ Ihre Kunden mit Autos sind. Im Grundmodell sollte er Zugriff auf die caraggregierte Wurzel haben. Sie können auch Situationen wie die in der Zeichnung zulassen. Die richtige Lösung hängt vom Geschäftsmodell der Anwendung ab. Es kann in jedem Fall anders sein.
Marcin Szymczak
1
@MarcinSzymczak richtig, könnte nicht mehr zustimmen, dass die Lösung vom Domain-Modell selbst abhängt
Parama Dharmika
Tatsächlich ist das Rad ein Aggregat, das Reifen (und andere Teile) enthält. Wenn Ihre Regeln vorschreiben, dass auf das Radaggregat nur über das Auto-Wurzelaggregat zugegriffen werden kann, ist die Engine auch im Auto-Wurzelaggregat enthalten und sollte nicht außerhalb des Autos aufgerufen werden. Das ist im Bereich einer Auto-Instanz. Ein Autobesitzer (Kunde) würde einen Motor nur im Zusammenhang mit seinem Auto referenzieren.
Ibrahim Malluf
35

Stellen Sie sich vor, Sie haben eine Computer-Entität. Diese Entität kann auch nicht ohne ihre Software-Entität und Hardware-Entität leben. Diese bilden das ComputerAggregat, das Mini-Ökosystem für den Computer-Teil der Domäne.

Aggregate Root ist die Mutterschiff-Entität innerhalb des Aggregats (in unserem Fall Computer). Es ist üblich, dass Ihr Repository nur mit den Entitäten arbeitet, die Aggregate Roots sind, und diese Entität ist für die Initialisierung der anderen Entitäten verantwortlich.

Betrachten Sie Aggregate Root als Einstiegspunkt in ein Aggregat.

Im C # -Code:

public class Computer : IEntity, IAggregateRoot
{
    public Hardware Hardware { get; set; }
    public Software Software { get; set; }
}

public class Hardware : IEntity { }
public class Software : IValueObject { }

public class Repository<T> : IRepository<T> where T : IAggregateRoot {}

Denken Sie daran, dass Hardware wahrscheinlich auch ein ValueObject ist (Sie haben keine eigene Identität). Betrachten Sie es nur als Beispiel.

Francisco Aquino
quelle
6
where T : IAggregateRoot- Dieser machte meinen Tag
Cristian E.
Der Wortlaut ist ein wenig widersprüchlich, denke ich, und das verwirrt mich, wenn ich versuche, dies zu lernen. Sie sagen, dass der Computer das Aggregat ist, aber dann sagen Sie, dass die Wurzel die Mutterschiff-Entität INNERHALB des Aggregats wäre. Welches ist in diesem Beispiel die "Mutterschiff" -Entität innerhalb des Aggregats?
Sinaesthetic
Grüße aus der Zukunft!. Was der Typ meint ist, dass der Computer selbst die aggregierte Wurzel ist, während der Computer UND alles darin das Aggregat ist. Oder klarer: Der Fall an sich ist die aggregierte Wurzel, während der gesamte Computer das Aggregat ist (die Sammlung von allem, was den "Computer ausmacht, z. B. RGB-Beleuchtung, Hardware, Netzteil, Betriebssystem usw.).
Captain Kenpachi
Die IAggregateRoot-Technik wird in der Microsoft-Dokumentation angezeigt
Samuel Danielson
16

Wenn Sie einen Datenbank-First-Ansatz verfolgen, ist Ihr aggregierter Stamm normalerweise die Tabelle auf der 1-Seite einer 1-Many-Beziehung.

Das häufigste Beispiel ist eine Person. Jede Person hat viele Adressen, eine oder mehrere Gehaltsabrechnungen, Rechnungen, CRM-Einträge usw. Dies ist nicht immer der Fall, aber 9/10 Mal.

Wir arbeiten derzeit an einer E-Commerce-Plattform und haben grundsätzlich zwei aggregierte Wurzeln:

  1. Kunden
  2. Verkäufer

Kunden geben Kontaktinformationen an, wir weisen ihnen Transaktionen zu, Transaktionen erhalten Werbebuchungen usw.

Verkäufer verkaufen Produkte, haben Kontaktpersonen, über uns Seiten, Sonderangebote usw.

Diese werden vom Kunden- bzw. Verkäufer-Repository erledigt.

Kapitän Kenpachi
quelle
8
Wenn Sie einen Datenbank-First-Ansatz verfolgen, üben Sie kein domänengesteuertes Design, sondern ein datengesteuertes Design.
Sinaesthetic
5
Es ist ein Q & A-Forum, in dem Leute kommen, um Probleme zu lösen und / oder zu lernen - das habe ich nicht angestupst. Per Definition ist DDD mehr als alles andere eine Denkweise, die für viele verwirrend ist. Daher habe ich dafür gesorgt, dass der Kommentar für diejenigen abgegeben wurde, die DDD lernen, um mögliche Konflikte zwischen Entwurfsmethoden zu vermeiden.
Sinaesthetic
12

Dinah:

Im Kontext eines Repositorys ist der aggregierte Stamm eine Entität ohne übergeordnete Entität. Es enthält null, eine oder viele untergeordnete Entitäten, deren Existenz hinsichtlich ihrer Identität vom Elternteil abhängt. Das ist eine Eins-zu-Viele-Beziehung in einem Repository. Diese untergeordneten Einheiten sind einfache Aggregate.

Geben Sie hier die Bildbeschreibung ein

Ibrahim Malluf
quelle
1
Wenn Sie also ein Autoverkäufer sind, wäre Car eine eigenständige Gesamtwurzel? Weil Sie viele Autos haben können, die noch keinen Kunden haben
JorgeeFG
2
@JorgeeFG Die wahre Antwort ist, dass niemand irgendeine Ahnung hat. Es gibt so viele widersprüchliche Informationen.
Mardoxx
3
Untergeordnete Entitäten sind keine Aggregate, sondern nur Entitäten, die zufällig Mitglieder des Aggregats sind, in dem der Aggregatstamm steuert. Ein "Aggregat" ist eine logische Gruppierung von Entitäten.
Sinaesthetic
@JorgeeFG es hängt wirklich von dem begrenzten Kontext ab, den Sie entwerfen. Wenn Sie ein Autoverkäufer sind, dann wird so etwas wie ein Carshop zur Gesamtwurzel, und darunter folgt das
Auto
8

Von einem defekten Link :

Innerhalb eines Aggregats gibt es eine Aggregatwurzel. Der Aggregatstamm ist die übergeordnete Entität aller anderen Entitäten und Wertobjekte innerhalb des Aggregats.

Ein Repository arbeitet mit einem aggregierten Stamm.

Weitere Infos finden Sie auch hier .

Otávio Décio
quelle
4
Vielen Dank. Das ist definitiv die häufigste und frustrierendste defekte Verbindung, auf die ich ständig gestoßen bin.
Dinah
Auch der Wortlaut scheint rückwärts. Wie kann die Wurzel innerhalb des Aggreate sein und gleichzeitig übergeordnet sein?
Sinaesthetic
1
Die aggregierte Wurzel ist die Wurzelklasse. Ein einfaches Aggregat ist immer in einer Aggregatwurzel enthalten. Verwenden des oben dargestellten Diagramms ... Der Kunde ist die Aggregatwurzel. Der Kunde kann ein oder mehrere Autos besitzen. Autos sind Aggregate in Bezug auf den Kunden. Autos haben einen Motor. Der Motor ist ein Aggregat, das im Autoaggregat enthalten ist. Was den Kunden zu einer Gesamtwurzel macht, ist die Annahme des Modells, dass der Zugriff auf ein Auto oder seine Komponenten immer über den Kunden erfolgt, dem das Auto gehört.
Ibrahim Malluf
8

Aggregat bedeutet Sammlung von etwas.
root ist wie der oberste Knoten des Baums, von wo aus wir auf alles zugreifen können, was wie ein <html>Knoten im Webseitendokument ist.
Blog-Analogie, Ein Benutzer kann viele Beiträge haben und jeder Beitrag kann viele Kommentare haben. Wenn wir also einen Benutzer abrufen, kann dieser als Root fungieren, um auf alle zugehörigen Beiträge und weitere Kommentare dieser Beiträge zuzugreifen. Diese werden alle zusammen als Sammlung oder aggregiert bezeichnet

palash140
quelle
1

Mit Aggregate schützen Sie Ihre Invarianten und erzwingen die Konsistenz, indem Sie den Zugriff auf die Aggregatwurzel einschränken. Vergessen Sie nicht, dass das Aggregat auf den Geschäftsregeln und Invarianten Ihres Projekts basieren sollte, nicht auf der Datenbankbeziehung. Sie sollten kein Repository einfügen und keine Abfragen sind nicht zulässig.

Alireza Rahmani Khalili
quelle