Frage

Lassen Sie uns sagen, dass wir ein Aggregat Stammentität vom Typ Auftrag haben, die Kunden und Auftragspositionen betrifft. Wenn ich zu einer Bestellung Einheit denken, ist es natürlicher, es konzeptionieren nicht ohne Id definiert ist. Eine Bestellung ohne Id besser als Auftragsanforderung als ein Auftrag vertreten zu sein scheint.

Um eine Bestellung zu einem Repository hinzufügen, ich in der Regel sehen die Menschen den Auftrag ohne die Id instanziiert und haben dann das Repository vollständig um das Objekt:

class OrderRepository
{
    void Add(Order order)
    {
        // Insert order into db and populate Id of new order
    }
}

Was ich über diesen Ansatz gefällt, ist, dass Sie eine Order-Instanz in eine OrderRepository hinzufügen. Das macht sehr viel Sinn. Allerdings ist die Reihenfolge Instanz keine ID hat, und im Rahmen des Verbrauchers des Endlagers, macht es noch keinen Sinn für mich, dass ein Auftrag nicht eine Id hat. Ich konnte ein Orderrequest sein eine Instanz, um zu definieren und dass in das Repository hinzufügen, aber das fühlt sich an wie einen Apfel von einem orangefarbenen abgeleitet und dann auf eine Liste von Orangen hinzufügen.

Alternativ habe ich auch diesen Ansatz gesehen:

class OrderRepository
{
    Order AddOrder(Customer customer)
        // It might be better to call this CreateOrder
    {
        // Insert record into db and return a new instance of Order
    }
}

Was ich über diesen Ansatz gefällt, ist, dass eine Bestellung ohne Id nicht definiert ist. Das Repository kann den Datenbankeintrag erstellen und sammeln Sie alle erforderlichen Felder vor dem Erstellen und eine Instanz einer Bestellung zurück. Was hier riecht, ist die Tatsache, dass Sie nie eine Instanz eines Auftrages in das Repository tatsächlich hinzuzufügen.

So oder so funktioniert, so ist meine Frage: Muss ich mit einem dieser beiden Interpretationen zu leben haben, oder gibt es eine bewährte Methode, die Einführung zu modellieren

Ich fand diese Antwort, die ähnlich ist, aber für Wertobjekte: wie soll ich ein Objekt hinzufügen in eine Sammlung von Aggregat gehalten root . Wenn es um ein Wertobjekt kommt gibt es keine Verwirrung, aber meine Frage betrifft ein Unternehmen mit identiy von einer externen Quelle abgeleitet (automatisch generierten Datenbank-ID).

War es hilfreich?

Lösung

würde ich den zweiten Ansatz Zunächst möchte ausschließt. Nicht nur, dass es scheint kontraintuitiv, es verstößt auch mehr guten Design-Prinzipien, wie zum Beispiel Befehl-Abfrage Trennung und die Prinzip der geringsten Überraschung .

hängen Die restlichen Optionen auf der Domain Logic. Wenn der Domain-Logik diktiert, dass ein Auftrag ohne ID bedeutungslos ist, ist die ID eine erforderliche Invariante Ordnung, und wir müssen sie modellieren so:

public class Order
{
    private readonly int id;

    public Order(int id)
    {
        // consider a Guard Clause here if you have constraints on the ID
        this.id = id;
    }
}

Beachten Sie, dass das id Feld als readonly durch Markierung haben wir es eine unveränderliche gemacht. Es gibt keine Art, wie wir es für eine bestimmte Bestellung Instanz ändern können. Dies passt perfekt mit Domain-Driven Design 's Entity Muster.

Sie können weitere Domain-Logik erzwingen durch einen Schutzklausel in den Konstruktor setzt von der ID zu verhindern, negativ oder Null ist.

Jetzt sind Sie wahrscheinlich fragen, wie diese möglicherweise Arbeit mit automatisch generierten IDs aus einer Datenbank. Nun, es funktioniert nicht.

Es gibt keinen guten Weg, um sicherzustellen, dass die gelieferten ID nicht bereits verwendet wird.

Das lässt Sie mit zwei Optionen:

  • Ändern Sie die ID auf einen Guid. Hierdurch kann jeder Anrufer eine eindeutige ID für eine neue Bestellung liefern. Dies erfordert jedoch Sie Guids als Datenbankschlüssel als auch zu verwenden.
  • Ändern Sie die API, so dass eine neue Ordnung zu schaffen keine Order-Objekt übernimmt, sondern ein Orderrequest wie Sie vorgeschlagen -. Die Orderrequest fast identisch mit der Order-Klasse sein könnte, abzüglich der ID

In vielen Fällen, eine neue Ordnung zu schaffen ist ein Geschäftsbetrieb, die spezielle Modellierung in jedem Fall benötigt, so sehe ich kein Problem, diese Unterscheidung zu machen. Obwohl Auftrag und Orderrequest semantisch sehr ähnlich sein können, müssen sie nicht einmal in der Typenhierarchie in Beziehung gesetzt werden.

ich sogar so weit gehen könnte zu sagen, dass sie sollte nicht in Beziehung gesetzt werden, weil Orderrequest ein ist Value Object , während Auftrag ist ein Entity .

Wenn dieser Ansatz gewählt wird, die AddOrder Methode muss eine Auftragsinstanz zurückgeben (oder zumindest die ID), denn sonst können wir nicht die ID der Bestellung wissen wir gerade erstellt haben. Dies führt uns zu CQS Verletzung zurück, weshalb ich dazu neigen, bevorzugt Guids für Entity-IDs .

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