Frage

hatte ich eine Diskussion bei der Arbeit in Bezug auf „Vererbung in Domänenmodell ist Entwickler Leben zu verkomplizieren“. Ich bin ein OO-Programmierer so dass ich für Argumente zu suchen begann, dass in Domänenmodell Vererbung hat, wird der Entwickler das Leben erleichtern tatsächlich statt schaltet alle über den Ort hat.

Was ich sehen möchte, ist dies:

class Animal {

}

class Cat : Animal {

}

class Dog : Animal {

}

Was der andere Kollege sagt, ist:

public enum AnimalType {
    Unknown,
    Cat,
    Dog
}

public class Animal {

    public AnimalType Type { get; set; }

}

Wie kann ich ihn überzeugen (Links sind WELCOME ), dass eine Hierarchie Klasse besser wäre als eine Aufzählungseigenschaft für diese Art von Situationen?

Danke!

War es hilfreich?

Lösung

Hier ist, wie ich Grund dazu:

Verwenden Sie nur Vererbung, wenn die Rolle / Typ wird sich nie ändern. z.B.

mit Vererbung für Dinge wie:

Fireman <- Mitarbeiter <-. Person ist falsch

sobald Freddy der Feuerwehrmann Jobwechsel oder arbeitslos wird, müssen Sie ihn töten und ein neues Objekt des neuen Typs mit all den alten Beziehungen neu zu ihm angebracht.

So ist die naive Lösung für das obige Problem wäre, einen Jobtitel Enum-Eigenschaft auf der Person-Klasse zu geben. Dies kann genug, um in einigen Szenarien, z.B. wenn Sie nicht brauchen, sehr komplexe Verhaltensweisen mit der Rolle / Typ zugeordnet ist.

Je mehr richtige Weg wäre, der Person Klasse eine Liste von Rollen zu geben. Jede Rolle stellt beispiel eine Beschäftigung mit einer Zeitspanne.

z.

freddy.Roles.Add(new Employement( employmentDate, jobTitle ));

oder wenn das viel des Guten:

freddy.CurrentEmployment = new Employement( employmentDate, jobTitle );

Auf diese Weise kann Freddy ein Entwickler wird w / o wir ihn zuerst töten zu müssen.

Doch alle meine Geschwafel noch nicht beantwortet haben, wenn Sie eine ENUM oder Typhierarchie für die Jobtitel verwendet werden soll.

In der reinen in mem OO Ich würde sagen, dass es richtiger ist hier Erbe für die jobtitles zu verwenden.

Aber wenn Sie O / R-Mapping tun Sie mit ein bisschen überkomplexen Datenmodell hinter den Kulissen enden könnte, wenn der Mapper jede Untertyp in eine neue Tabelle abzubilden versucht. Also in solchen Fällen, gehe ich oft für die ENUM-Ansatz, wenn es keine wirkliche / komplexes Verhalten ist mit den Typen zugeordnet. Ich kann mit einem leben „wenn Typ == JobTitles.Fireman ...“, wenn die Nutzung beschränkt ist, und es macht die Dinge easer oder weniger komplex.

z. Entity Framework 4-Designer für .NET kann nur jeden Untertyp in eine neue Tabelle zuordnen. und Sie könnten eine hässliche Modell bekommen oder eine Menge schließt sich, wenn Sie Ihre Datenbank abfragen w / o einen wirklichen Nutzen.

Jedoch habe ich Verwendung Vererbung zu tun, wenn der Typ / Rolle ist statisch. z.B. für Produkte.

Sie haben könnten CD <- Produkt- und Book <- Produkt. Vererbung gewinnt hier, weil in diesem Fall, dass Sie höchstwahrscheinlich anderen Zustand mit den Typen zugeordnet. CD könnte eine Reihe von Spuren Eigenschaft hat, während ein Buch Seitenzahl Eigenschaft haben könnte.

Also kurz gesagt, es hängt davon ab, -)

Auch am Ende des Tages werden Sie höchstwahrscheinlich mit vielen Switch-Anweisungen oder so enden. Angenommen, Sie haben ein „Produkt“ zu bearbeiten wollen, auch wenn Sie die Vererbung verwenden, werden Sie wahrscheinlich Code wie folgt aussehen:

if (Produkt Buch)         Response.Redicted ( "~ / EditBook.aspx id?" + Product.id);

Da Kodieren der Bearbeitungs Buch URL in der Entity-Klasse Ebene wäre hässlich, da es Ihre Unternehmen entites zwingen würde, über Ihre Website-Struktur zu wissen, etc.

Andere Tipps

Aufzählungen sind gut, wenn:

  1. Der Satz von Werten festgelegt ist und nie oder sehr selten ändert.
  2. Sie wollen eine Union der Werte darstellen können (das heißt die Kombination von Flags).
  3. Sie brauchen nicht auf anderen Zustand zu jedem Wert zu befestigen. (Java nicht über diese Einschränkung.)

Wenn Sie Ihr Problem mit einer Reihe lösen könnten, eine Enumeration ist wahrscheinlich eine gute Passform und mehr Art sicher. Wenn Sie mehr Flexibilität als die oben benötigen, sind dann Aufzählungen wahrscheinlich nicht die richtige Antwort. Mit polymorphen Klassen können Sie:

  1. Statisch sicherzustellen, dass alle typspezifischen Verhalten behandelt wird. Zum Beispiel, wenn Sie alle Tiere müssen Bark() zu können, Animal Klassen mit einer abstrakten Bark() Methode macht für Sie die Compiler-Check lassen, dass jede Unterklasse implementiert sie. Wenn Sie eine ENUM und einen großen switch verwenden, wird es nicht sicher, dass Sie jeden Fall behandelt haben.

  2. können Sie fügen neue Fälle (Arten von Tieren in Ihrem Beispiel). Dies kann über Quelldateien durchgeführt werden, und sogar über Paketgrenzen. Mit einem Enum, wenn man es erklärt hat, ist es gefriert. Open-End-Erweiterung ist eine der wichtigsten Stärken der OOP.

Es ist wichtig zu beachten Sie, dass Ihre Kollegen Beispiel ist nicht in direktem Gegensatz zu Ihnen. Wenn er eines Tieres Art will eine exponierte Eigenschaft sein (was für manche Dinge nützlich ist), können Sie das tun, ohne eine ENUM zu verwenden, mit der Typ Objektmuster :

public abstract class AnimalType {
    public static AnimalType Unknown { get; private set; }
    public static AnimalType Cat { get; private set; }
    public static AnimalType Dog { get; private set; }

    static AnimalType() {
        Unknown = new AnimalType("Unknown");
        Cat = new AnimalType("Cat");
        Dog = new AnimalType("Dog");
    }
}

public class Animal {
    public AnimalType Type { get; set; }
}

Das gibt Ihnen den Komfort eines ENUM: Sie AnimalType.Cat tun können, und Sie den Typ eines Tieres zu bekommen. Aber es gibt Ihnen auch die Flexibilität der Klassen: Sie Felder AnimalType hinzufügen können mit jeder Art zusätzliche Daten zu speichern, fügen Sie virtuelle Methoden usw. Noch wichtiger ist, können Sie neue Tierarten definieren, indem nur neue Instanzen von AnimalType Erstellen

Ich würde Sie bitten, zu überdenken: in einem anämischen Domänenmodell (gemäß den obigen Ausführungen ), Katzen nicht verhalten anders als Hunde, so gibt es keinen Polymorphismus. Der Typ eines Tieres ist wirklich nur ein Attribut. Es ist schwer, was Erbe kauft sie dort zu sehen.

Mit einer Enum ist wie eine Party für alle jene Open/Closed Principle is for suckers Menschen zu werfen.

Es lädt Dich wirklich zu überprüfen, ob ein Tier einer bestimmten Art ist, und dann gilt für jede Art individuelle Logik. Und das kann schrecklich Code machen, die es wirklich schwer machen auf Ihrem System weiter auszubauen.

Am wichtigsten ist OOPS Mittel Modellierung der Realität. Vererbung gibt Ihnen die Möglichkeit zu sagen, Katze ist ein Tier. Tier soll nicht wissen, ob seine eine Katze jetzt ist es schreit und dann entscheiden, dass es zu Meow annahm und nicht Bark, Encapsulation wird es besiegt. Weniger Code wie jetzt Sie müssen nicht tun, wie Sie Wenn anderes gesagt.

Beide Lösungen sind richtig. Sie sollten besser zu Ihnen Problem aussehen, welche Techniken angewendet wird.

Wenn Ihr Programm paar verschiedene Objekte verwendet, und fügt keine neuen Klassen, ist es besser, mit Aufzählungen zu bleiben.

Aber wenn Sie verwendet eine Menge von verschiedenen Objekten (unterschiedliche Klassen) programmieren und kann neue Klassen hinzuzufügen, in Zukunft versuchen, besser das Erbe Art und Weise.

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