Frage

Dies ist eine praktische Domain Driven Design Frage:

Konzeptionell, ich glaube, ich Aggregate Wurzeln bekommen, bis ich gehe ein zu definieren.

Ich habe eine Employee-Entität, die als Aggregate Wurzel aufgetaucht ist. Im Geschäft, einige Mitarbeiter können arbeitsbedingte Verstöße protokolliert gegen sie:

Mitarbeiter ----- * Verletzungen

Da nicht alle Mitarbeiter unterliegen diese sind, würde ich denken, dass Verstöße gegen das wäre ein Teil der Mitarbeiter Aggregate nicht sein, oder?

Also, wenn ich mit Mitarbeitern und die damit verbundenen Verletzungen arbeiten will, sind dies zwei separaten Repository Interaktionen von einigen Service-?

Schließlich, wenn ich eine Verletzung hinzuzufügen, ist das Verfahren auf der Employee-Entität? Danke für die Hilfe!

War es hilfreich?

Lösung

Nach dem sogar noch mehr Forschung zu tun, ich glaube, ich habe die Antwort auf meine Frage.

Paul Stovell hatte diese leicht bearbeiten Antwort auf eine ähnliche Frage auf dem DDD Messageboard . Substitute „Kunde“ für „Mitarbeiter“ und „Order“ für „Verletzung“ und Sie bekommen die Idee.

  

Nur weil Kundenreferenzen bestellen   bedeutet nicht unbedingt Auftrag fällt   innerhalb des Kunden Aggregat Wurzel.   Die Kunden-Adressen könnte, aber   Die Aufträge können unabhängig sein (für   Sie könnten beispielsweise einen Dienst haben,   verarbeitet alle ganz gleich neue Aufträge, die   der Kunde ist. Mit gehen   Kunden-> Orden macht keinen Sinn, in   Dieses Szenario).

     

Aus fachlicher Sicht, können Sie   Frage sogar die Gültigkeit dieser   Referenzen (Kunde hat Verweis auf   eine Liste der Aufträge). Wie oft werden Sie   tatsächlich benötigen alle Aufträge für eine   Kunde? In einigen Systemen macht es   Sinn, aber in anderen, einem Kunden   könnten viele Aufträge machen. Die Chancen stehen gut   Sie möchten Aufträge für einen Kunden zwischen   ein Datumsbereich oder Aufträge für einen Kunden   , die noch nicht oder Bestellungen   die nicht bezahlt wurden, und so weiter.   Das Szenario, in dem Sie alle brauchen   von ihnen könnten relativ selten sein.   Allerdings ist es viel wahrscheinlicher, dass   wenn sie mit einem Auftrag zu tun, werden Sie   wollen die Kundeninformationen. so in   Code, Order.Customer.Name ist nützlich,   aber Customer.Orders[0].LineItem.SKU -   wahrscheinlich nicht so nützlich. Na sicher,   das hängt ganz auf Ihr Unternehmen   Domäne.

Mit anderen Worten, Kunde aktualisiert hat nichts mit der Aktualisierung von Bestellungen zu tun. Und Aufträge oder Verletzungen in meinem Fall denkbar könnten unabhängig von Kunden / Mitarbeitern behandelt werden.

Wenn Verstöße Detaillinien haben, dann Verletzung und Verletzung Linie wären dann ein Teil des gleichen Aggregats sein, weil eine Verletzung Linie ändern wahrscheinlich eine Verletzung beeinflussen würden.

EDIT ** Die Falten hier in meiner Domain ist, dass Verstöße gegen das kein Verhalten. Sie sind im Grunde Aufzeichnungen eines Ereignisses, das passiert ist. Noch nicht sicher über die Auswirkungen, die hat.

Andere Tipps

Eric Evan in seinem Buch, Domain-Driven Design: Bewältigung der Komplexität im Herzen von Software

  

Ein Aggregat ist eine Gruppe von zugehörigen Objekten, die wir als eine Einheit behandeln zum Zweck der Datenänderungen .

Es gibt zwei wichtige Punkte hier:

  1. sollten diese Objekte als „Einheit“ behandelt werden.
  2. Für die Zwecke der "Datenänderung".

Ich glaube, in Ihrem Szenario, Mitarbeiter und Verletzung ist nicht unbedingt eine Einheit zusammen, während im Beispiel der Ordnung und OrderItem, sie ist Teil einer einzigen Einheit sind.

Eine andere Sache, die wichtig ist, wenn die agggregate Grenzen der Modellierung ist, ob Sie Invarianten in Ihrem Aggregat haben. Invarianten sind Geschäftsregeln, die in der „ganzen“ Aggregat gültig sein sollte. Zum Beispiel, wie für den Orden und OrderItem Beispiel könnte man eine Invariante hat, dass die Gesamtkosten der Bestellung Staaten sollten als eine vorgegebene Menge weniger. In diesem Fall, wann immer Sie eine OrderItem zum Auftrag hinzufügen möchten, sollte diese Invarianten, um sicherzustellen, werden erzwungen, dass Ihre Bestellung gültig ist. Doch in Ihrem Problem, ich sehe keine Invarianten zwischen Entitäten: Mitarbeiter und Verletzung.

So kurze Antwort:

Ich glaube, Mitarbeiter und Verletzung gehört jeweils zu 2 separaten Aggregaten. Jede dieser Einheiten sind auch ihre eigenen Aggregat Wurzeln. Sie müssen also 2 Repositories: EmployeeRepository und ViolationRepository.

Ich glaube auch, sollten Sie eine unidirektionale Assoziation von Verletzung zu Mitarbeitern haben. Auf diese Weise jede Verletzung Objekt weiß, wem es gehört. Aber wenn Sie die Liste aller Verstöße für einen bestimmten Mitarbeiter erhalten möchten, dann können Sie die ViolationRepository fragen:

var list = repository.FindAllViolationsByEmployee(someEmployee);

Sie sagen, dass Sie Mitarbeiter Einheit haben und Verletzungen und jede Verletzung hat kein Verhalten selbst. Von dem, was ich oben lesen kann, so scheint es mir, dass Sie zwei Aggregate Wurzeln haben:

  • Mitarbeiter
  • EmployeeViolations (nennen wir es EmployeeViolationCard oder EmployeeViolationRecords)

EmployeeViolations wird durch den gleichen Mitarbeiter-ID identifiziert und es hält eine Sammlung von Objekten Verletzung. Sie erhalten Verhalten für Mitarbeiter und Verletzungen auf diese Weise getrennt und bekommt man nicht Verletzung Einheit ohne Verhalten.

Ob Verletzung Einheit oder Wertobjekt Sie auf der Grundlage seiner Eigenschaften entscheiden sollte.

Ich bin damit einverstanden allgemein mit Mosh auf diesem. Allerdings hält, den Begriff der Transaktionen im betriebswirtschaftlichen Sicht im Auge behalten. Also nehme ich eigentlich „für die Zwecke der Datenänderungen“ bedeuten „für die Zwecke der Transaktion (s)“.

Repositorys sind Ansichten des Domänenmodell. In einer Domänenumgebung, diese „Ansichten“ wirklich unterstützen oder auf Geschäftsreise oder Fähigkeit dar - eine Transaktion. Typischer Fall, kann der Arbeitnehmer eine oder mehr Verletzungen, und wenn ja, sind Aspekte einer Transaktion (en) in einem Zeitpunkt. Betrachten Sie Ihre Anwendungsfälle.

Szenario: „Ein Mitarbeiter eine Tat begeht, die eine Verletzung des Arbeitsplatz ist.“ Dies ist eine Art von Business-Event (das heißt Transaktion oder Teil einer größeren, vielleicht verteilte Transaktion), die aufgetreten ist. Die Wurzel betroffenen Domänenobjekt kann tatsächlich aus mehr als einer Perspektive gesehen werden, weshalb es verwirrend ist. Aber die Sache zu erinnern ist, Verhalten, wie es zu einem Geschäftsvorgang betrifft, da Sie Ihre Geschäftsprozesse die reale Welt so genau wie möglich zu modellieren. In Bezug auf die Beziehungen, wie in einer relationalen Datenbank, Ihr konzeptionelles Domänenmodell sollte angeben, tatsächlich diese bereits (das heißt die Assoziativität), die oft in beiden Richtungen gelesen werden kann:

Mitarbeiter <---- begeht ein ------- begangen ----> Verletzung

Also für diesen Anwendungsfall wäre es fair, dass zu sagen, dass es eine Transaktion mit Verletzungen zu tun ist, und dass die Wurzel - oder „primäre“ Einheit - ist eine Verletzung. Das wäre dann Aggregat Wurzel, die Sie für diese bestimmte Geschäftstätigkeit oder Geschäftsprozess verweisen würde. Aber das ist nicht zu sagen, dass, für eine andere Tätigkeit oder den Prozess, dass Sie nicht einen Mitarbeiter Aggregat Wurzel, wie der „neuen Mitarbeiter Prozess“ haben können. Wenn Sie darauf achten, soll es keine negativen Auswirkungen der zyklischen Referenzen sein, oder in der Lage, Ihre Domain-Modell mehr Möglichkeiten zu durchqueren. Ich werde warnen jedoch, dass Regierungs dies sollte etwa gedacht werden und von dem Controller Stück Ihres Unternehmens Bereich behandelt, oder was auch immer gleichwertig Sie haben.

Neben: Das Denken in Mustern (das heißt MVC), das Repository ist eine Ansicht, die Domain-Objekte das Modell, und so sollte man auch irgendeine Form von Controller-Muster verwenden. Typischerweise erklärt der Controller die konkrete Umsetzung und den Zugang zu den Repositories (Sammlungen von aggregierten Wurzeln).

In der Datenzugriffs Welt ...

Mit LINQ to SQL als Beispiel, würde die Datacontext kann der Controller einen Blick auf Kunden- und Auftragseinheiten auszusetzen. Die Ansicht ist eine nicht-deklarativen, gerüst orientierten Tabellentyp (Grob entspricht Repository). Beachten Sie, dass die Ansicht, die einen Bezug zu seiner übergeordneten Steuerung hält, und geht oft über den Controller zu steuern, wie / wann die Ansicht materialisiert wird. Somit ist die Steuerung Ihres Providers, die Pflege-Mapping, Übersetzung, Objekt Hydratation usw. Das Modell ist dann Ihre Daten POCOs. Ziemlich viel ein typisches MVC-Muster.

Mit der Taste N / Hibernate als Beispiel, würde die ISession sein der Controller eine Ansicht von Kunden- und Auftragseinheiten über die session.Enumerable (string query) oder session.Get (Objekt-ID) oder session.CreateCriteria aussetzt (typeof (Kunde)). List ()

In der Business-Logik Welt ...

Customer { /*...*/ }

Employee { /*...*/ }

Repository<T> : IRepository<T>
              , IEnumerable<T>
              //, IQueryable<T>, IQueryProvider //optional

{ /**/ }

BusinessController {
 Repository<Customer>  Customers { get{ /*...*/ }} //aggregate root
 Repository<Order> Orders { get{ /*...*/ }} // aggregate root
}

Auf den Punkt gebracht, lassen Sie Ihre Geschäftsprozesse und Transaktionen der Führer sein, und lassen Sie Ihre Business-Infrastruktur natürlich entwickeln, wie Prozesse / Aktivitäten umgesetzt werden oder Refactoring. Darüber hinaus bevorzugen composability gegenüber traditionellen Black-Box-Design. Wenn Sie zu Service-orientierten oder Cloud Computing, werden Sie froh, dass Sie getan haben. :)

Ich habe mich gefragt, was die Schlussfolgerung wäre?

'Verstöße' zu einer Root-Entität. Und ‚Verletzungen‘ würden durch ‚Arbeitnehmer‘ Root-Entität referenziert werden. dh Verletzungen Repository <-> Mitarbeiter Repository

Aber Sie sind consfused über Verletzungen eine Stammentität machen becuase es kein Verhalten hat.

Aber ist ‚Verhalten‘ ein Kriterium als Root-Entität zu qualifizieren? Ich denke nicht so.

eine leicht orthogonal Frage Verständnis hier zu testen, zu bestellen zurück ... OrderItem Beispiel könne es ein Analysemodul im System sein, das in Orderitem direkt dh alle Orderitem für ein bestimmtes Produkt suchen will bekommen, oder alle bestellen Artikel größer als ein gegebener Wert usw., eine Menge usecases wie das macht mit und „Aggregat root“ extremen Fahr könnten wir argumentieren, dass OrderItem ein anderes Aggregat Wurzel an sich ist ??

Es hängt davon ab. Hat jede Änderung / hinzufügen / löschen einer Verletzung eines Teils der Arbeitnehmer ändern - zum Beispiel sind Speichern Sie Verletzung zählen, oder in den vergangenen 3 Jahre gegen Mitarbeiter zählen Verletzung?

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