2009-08-26 11 views
9

Lasst sie sagen, dass ich AutoDDD: Subklassen & Stammentität

class Car : Entity 
{ 
    public double MaxSpeed { get; set; } 
    public Color Color { get; set; } 
    /* ... */ 
} 

Diese Einheit, in meinem Domain-Modell wäre die Stammentität ein Aggregat die typische Einheit habe.

Jetzt sagen wir, ich spezialisiere Autos. Ich erstelle ein Ferrari und die glücklichen Besitzer von Ferraris wie sie durch einen Spitznamen nennen:

class Ferrari : Car 
{ 
    public string Nickname { get; set; } 
} 

Lassen Sie uns sagen, dass ich ein anderes Unternehmen haben, die Firma Einheit. Es wäre die Wurzeleinheit eines anderen Aggregats. Es gibt viele Leute, die an einer Firma arbeiten, vertreten durch die Entität Person. Personen dürfen Autos haben. Aber der Präsident ein Unternehmen ist in der Regel sehr reich und diese Art von Menschen, haben sie Ferraris:

class President : Person 
{ 
    public Ferrari Ferrari { get; set; } 
} 

In dieser Situation habe ich das Unternehmen Präsidenten, die innerhalb die Firma Aggregate sind, das einen Verweis auf einen Ferrari enthält, eine Spezialisierung der Stammeinheit eines anderen Aggregats.

Ist das im Hinblick auf DDD korrekt? Kann/sollte ich die Spezialisierung von Wurzel-Entitäten selbst als Wurzel-Entitäten desselben Aggregats betrachten? Ich meine, in der Domäne, die ich beschrieben habe, ist die Entität Ferrari auch die Wurzel-Entität des Auto-Aggregats (da Ferrari auch ein Auto ist)?


Lassen Sie uns jetzt sagen, ich habe zu bestehen, dieses Modell zu einer Datenbank. Ich denke, dass meine Frage nicht von dem OR/M-Framework abhängt, das ich verwenden werde.

Wie soll ich den Tisch mit Autos bauen? Soll ich einen einzigen Tisch Autos bauen, mit einer "CarType" -Spalte (mögliche Werte: "Car", "Ferrari"), und einer Nullable-Nickname-Spalte?

Oder sollte ich einen Tisch für Autos und einen Tisch für Ferraris bauen, letzterer hat seinen PK einen FK von Cars?

Danke!

Antwort

2

Ich denke, dass Sie beginnen, viel von der Flexibilität des Systems zu verlieren, indem Sie konkrete Arten dieser Entitäten erstellen. Die Art der Beziehung, die Sie implizieren, ist etwas, das ich im Allgemeinen mit einer Entität "Typ" ausgehändigt habe. Zum Beispiel hast du ein Auto. Ein Ferrari ist eine Art von Auto. Die zwei Entitäten, die davon getragen werden, sind ein Auto und ein CarType.

Die Art, wie Sie darüber reden, Sie müssten jedes Mal, wenn ein neuer Typ eingeführt wird, neue Entitäten hinzufügen. Wenn alles, was Sie zu erfassen versuchen, der "Spitzname" des Autos ist, würde ich denken, dass das nur ein weiteres Stück Daten ist, und nicht eine andere Entität. Es sei denn, Sie haben andere Daten (z.Unterschiedliche Eigenschaftennamen) und/oder Verhaltensunterschiede in Car-Entitäten für verschiedene Typen, gewinnen Sie mit diesem Ansatz nicht viel. Ich würde lieber Repository-Methoden wie FindCarByType() haben und mit einem Entitätstyp umgehen, um das Risiko zu reduzieren.

Ich bin auf keinen Fall ein DDD-Experte, und ich kämpfe mit einigen Konzepten (oder mehr wie mit den vielfältigen Interpretationen einiger Konzepte kämpfen). Ich stelle fest, dass es keine 100% ige Implementierung gibt und dass es bei jeder Implementierung Nuancen gibt, die ich gesehen habe.

bearbeiten Folgt

Ich sehe, dass ich falsch verstanden von dem, was Sie geschrieben hatte. Ich sehe diesen Spitznamen nicht für alle Fahrzeuge, sondern nur für Ferrari: Auto. Ich denke, dass die Antwort wirklich "hängt davon ab". Wie viel Domain-Spezialisierung haben Sie im Rest Ihres Modells? Ein Spitzname könnte unter den Ferrari-Entitäten vorherrschen, aber ist er exklusiv? Es geht nicht nur um die eigentlichen Daten, sondern um die Anforderungen. Grundsätzlich kommt es darauf an, wie viel Spezialisierung Sie in diesen Entitäten erwarten.

+0

Fantastisch! Vielen Dank! Eigentlich sind in meinem "echten" System "Autos" sehr wichtig, aber der "Ferrari" ist das wichtigste Ding in meiner Domäne, von dem ich nicht den Überblick verlieren kann, ich muss Statistiken darüber machen. –

4

Sie sollten keine Vererbung verwenden, um Ihre Domäne zu modellieren, da Sie bald in Schwierigkeiten geraten werden, sobald das Modell zu komplex wird.

Präsident ist einfach eine Rolle der Person und Person kann mehrere Rollen haben. Vielleicht hat der Präsident nur eine Rolle bekommen, aber das ist einfach Zufall, indem er ein falsches Beispiel gewählt hat.

Ferrari sollte auch nicht vom Auto vererbt werden. Es ist nicht offensichtlich auf Ferrari-Beispiel, weil sie nur eine Art von Autos tun, sondern darüber nachdenken, Firma viele Arten wie Lieferwagen, Limousinen, Hecktürmodelle, Lastwagen und so weiter zu machen. Sie werden wahrscheinlich Klassen für jeden Typ erstellen wollen, der von der Autoklasse erbt. Und dann, was ... wirst du fünf Toyota-Klassen machen, die von jedem Typ erben werden? Wie zum Beispiel ...

Car -> Sedan -> ToyotaSedan 
Car -> Truck -> ToyotaTruck 
Car -> Hatchback -> ToyotaHatchback 

Das wäre lächerlich.

Haftungsausschluss: Ich weiß nichts über Autos. Allerdings ...

Verwenden Sie keine Vererbung, um Ihre Domain zu modellieren. Je.

Versuchen Sie es ohne Vererbung und es wird auch offensichtlich, wie Sie Ihre Domain beibehalten.

+0

Danke, lubos.Aber in diesem Fall, in meiner "echten" Domäne, habe ich * "Autos", und es gibt "generische" Autos und zwei spezielle Arten von Autos, "Ferrari" und "Porsche", die aufgespürt werden müssen, obwohl sie es sind im Wesentlichen "Autos". –

+3

immer noch, Vererbung vermeiden. Selbst wenn Sie dies nicht tun, müssen Sie dies in ein oder zwei Jahren tun, da Ihr Modell in Zukunft wahrscheinlich komplizierter wird, um neue Anforderungen zu erfassen, und die Vererbung wird Ihnen viel Schmerz in Ihrem Design bereiten. Lehrbuch Beispiele zur Erklärung der Vererbung wie Katze und Hund sind beide Tiere und Kreis und Quadrat sind beide Formen geben einen falschen Eindruck, wofür Vererbung wirklich ist und Programmierer missbrauchen dieses mächtige Konzept für die Modellierung von Domänen. Lesen Sie hier mehr: http://www.geocities.com/tablizer/oopbad.htm#overeng (Ich bin nicht der Autor) –

+0

Sehr guter Artikel! Vielen Dank! –

3

Wenn Sie Root-Aggregatgrenzen überschreiten, erlauben Sie im Allgemeinen nur, dass die Referenz die ID des anderen Root-Aggregats hat. Sie verwenden diese ID dann, um das andere Aggregat in seinem Repository nachzuschlagen.

Also in Ihrem Fall würden Sie wollen, dass Präsident eine Auto-ID hat und wenn Sie jemals etwas zum Auto des Präsidenten tun mussten, würden Sie die Auto-ID verwenden, um zum Lager zu gehen, um das Auto zu bekommen. Präsident würde keinen Bezug zum Auto selbst haben.

Nun zu diesem Ferrari. In der DDD-Standardterminologie ist das nur schwer durchzusetzen. Normalerweise würden Sie die Zuweisung eines Autos an einen Präsidenten bestätigen. Oder vielleicht gibt es einen CarBuyingService nur für Präsidenten, der dafür sorgt, dass Sie alles richtig machen. Normalerweise sind DDD-Spezialisierungen nicht selbst Root-Aggregate.

+0

Sie sind der einzige, der die Frage tatsächlich beantwortet hat –