7 Stimmen

DDD - Aggregatwurzeln und Erstellen von Verhaltensobjekten

Ich möchte um Ratschläge bitten, wie man vermeiden kann, Objekte zu schreiben, die reine Datencontainer sind.

Betrachten Sie die folgende Aggregatwurzel:

public class Post : IAggregateRoot
{
  List<Comment> Comments {get; set;}
}

Ist es in Anbetracht der Grundsätze, die die Funktionsweise von Aggregatwurzeln bestimmen, zulässig, den obigen Code wie folgt aufzurufen?

new Post().Comments.Add(New Comment("stuff"));

Oder ist das der richtige Weg?

public class Post : IAggregateRoot
{
      List<Comment> Comments {get; private set;}
      public void AddComment(string message)
      {
        Comments.Add(new Comment(message)); 
      }
}

Und zwar so:

new Post().AddComment("stuff");

Ist es das, was Eric Evan damit meint, dass Aggregatwurzeln atomar sind?

Wenn dies der Fall ist, bedeutet dies, dass Entitäten keine öffentlichen Setter haben, sondern stattdessen unterstützende Methoden (AddThis, RemoveThat)? Erzeugt man auf diese Weise Objekte mit vielfältigem Verhalten?

5voto

Vijay Patel Punkte 16000

Sie haben das Konzept der aggregierten Wurzeln richtig verstanden, aber bei Ihren beiden Optionen geht es eigentlich um die Umsetzung - und beide sind gültig.

Option 1

  • Vorteile: Ihre Entitätsschnittstelle bleibt recht sauber.

  • Nachteile: Die Add Methode benötigt Logik für um die Beziehung zwischen dem Post y el Comment (denke NHibernate). Sie können eine stark typisierte Sammlung erstellen und die Add-Methode außer Kraft setzen, oder Sie könnten Ereignisse zurück an die Post auf handhaben.

Option 2

  • Vorteile : Die Add/Remove Methoden bieten einen praktischen Platz für die Verdrahtungslogik.

  • Nachteile: Wenn die Anzahl der Sammlungseigenschaften wächst, kann es zu einer Explosion von Add/Remove Methoden. Außerdem müssen exponierte Sammlungen ReadOnly sein, um sicherzustellen, dass Comments werden immer mit den speziellen Methoden hinzugefügt/entfernt.

Ich bevorzuge Option 1 - ich verwende generische Sammlungen, die Ereignisse auslösen. IMHO fühlt sich das natürlicher an und ist für andere Entwickler einfacher zu programmieren. Obwohl andere auf SO haben anders ausgedrückt.

Wenn wir über Verhalten sprechen wir über das Anbringen von Logik an die Entität. Wenn Sie z. B. Folgendes stoppen möchten Comments nach 5 Tagen hinzugefügt wird, würden Sie die Post wenn man eine Comment gültig ist, und die Post würde die Logik für die Prüfung enthalten.

3voto

Marek Tihkan Punkte 1876

Ich würde mich für die zweite Option entscheiden.

Erstens möchte ich Sammlungen als IEnumerable anzeigen. Auf diese Weise ist es nicht möglich, die Liste so einfach zu manipulieren und sie ist vor unerwünschtem Verhalten geschützt. Regelmäßig prüfe ich in der Hinzufügungs- und Entfernungsmethode, ob das Objekt in der Liste enthalten ist oder nicht.

Zweitens ist es gekapselt, und ich kann anschließend etwas Logik hinzufügen.

Schließlich können Sie eine Methodenverkettung mit dieser Methode vornehmen, indem Sie selbst zurückkehren:

var post = new Post()
    .AddComment("My First comment")
    .AddComment("My Second comment")
    .Publish();

Wenn die AddX-Methode Ihre Entität zu sehr aufbläht, dann ist es möglich, sie mit Überladung zu tun:

var post = new Post()
    .Add(new Comment("My First comment"))
    .Add(new Comment("My Second comment"))
    .Publish();

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X