Ich frage mich, was in Bezug auf gutes OOP-Design, sauberen Code, Flexibilität und Vermeidung von Codegerüchen in Zukunft besser ist. Bildsituation, in der Sie viele sehr ähnliche Objekte haben, die Sie als Klassen darstellen müssen. Diese Klassen haben keine spezifische Funktionalität, sind nur Datenklassen und unterscheiden sich nur durch Namen (und Kontext). Beispiel:
Class A
{
String name;
string description;
}
Class B
{
String name;
String count;
String description;
}
Class C
{
String name;
String count;
String description;
String imageUrl;
}
Class D
{
String name;
String count;
}
Class E
{
String name;
String count;
String imageUrl;
String age;
}
Wäre es besser, sie in getrennten Klassen zu halten, um "bessere" Lesbarkeit zu erzielen, aber mit vielen Code-Wiederholungen, oder wäre es besser, die Vererbung zu verwenden, um trockener zu sein?
Durch die Verwendung der Vererbung erhalten Sie so etwas, aber Klassennamen verlieren ihre kontextbezogene Bedeutung (aufgrund des is-a, nicht des has-a):
Class A
{
String name;
String description;
}
Class B : A
{
String count;
}
Class C : B
{
String imageUrl;
}
Class D : C
{
String age;
}
Ich weiß, dass Vererbung nicht für die Wiederverwendung von Code verwendet wird und nicht verwendet werden sollte, aber ich sehe keine andere Möglichkeit, um die Wiederholung von Code in einem solchen Fall zu reduzieren.
quelle
Genau. Betrachten Sie dies aus dem Zusammenhang:
Welche Eigenschaften hat ein D? Erinnerst du dich? Was ist, wenn Sie die Hierarchie weiter verkomplizieren:
Und was ist dann, wenn Sie, Horror auf Horror, ein imageUrl-Feld zu F, aber nicht zu E hinzufügen möchten? Sie können es nicht von C und E ableiten.
Ich habe eine tatsächliche Situation gesehen, in der viele verschiedene Komponententypen einen Namen, eine ID und eine Beschreibung hatten. Aber das lag nicht in der Natur ihrer Bestandteile, es war nur ein Zufall. Jeder hatte eine ID, weil sie in einer Datenbank gespeichert waren. Der Name und die Beschreibung wurden angezeigt.
Produkte hatten aus ähnlichen Gründen auch eine ID, einen Namen und eine Beschreibung. Aber sie waren weder Komponenten noch Komponentenprodukte. Sie würden die beiden Dinge nie zusammen sehen.
Einige Entwickler hatten jedoch etwas über DRY gelesen und beschlossen, jeden Hinweis auf eine Vervielfältigung aus dem Code zu entfernen. Also nannte er alles ein Produkt und machte die Definition dieser Felder überflüssig. Sie wurden in Product definiert und alles, was diese Felder benötigt, kann aus Product abgeleitet werden.
Ich kann das nicht stark genug sagen: Das ist keine gute Idee.
Bei DRY geht es nicht darum, die Notwendigkeit gemeinsamer Eigenschaften zu beseitigen. Wenn ein Objekt kein Produkt ist, bezeichnen Sie es nicht als Produkt. Wenn für ein Produkt keine Beschreibung erforderlich ist, definieren Sie die Beschreibung nicht als Eigenschaft des Produkts.
Es kam schließlich vor, dass wir Komponenten ohne Beschreibung hatten. Also haben wir begonnen, Null-Beschreibungen in diesen Objekten zu haben. Nicht nullbar. Null. Immer. Für jedes Produkt vom Typ X ... oder später Y ... und N.
Dies ist ein schwerwiegender Verstoß gegen das Liskov-Substitutionsprinzip.
Bei DRY geht es darum, sich niemals in die Lage zu versetzen, einen Fehler an einer Stelle zu beheben und ihn an einer anderen Stelle zu vergessen. Dies wird nicht passieren, da Sie zwei Objekte mit derselben Eigenschaft haben. Noch nie. Also mach dir keine Sorgen.
Wenn der Kontext der Klassen deutlich macht, dass Sie sollten, was sehr selten sein wird, dann und nur dann sollten Sie eine gemeinsame Elternklasse in Betracht ziehen. Wenn es sich jedoch um Eigenschaften handelt, überlegen Sie, warum Sie stattdessen keine Schnittstelle verwenden.
quelle
Vererbung ist ein Weg, um polymorphes Verhalten zu erreichen. Wenn Ihre Klassen kein Verhalten aufweisen, ist die Vererbung nutzlos. In diesem Fall würde ich sie nicht einmal als Objekte / Klassen betrachten, sondern stattdessen als Strukturen.
Wenn Sie in der Lage sein möchten, verschiedene Strukturen in verschiedene Teile Ihres Verhaltens einzufügen, ziehen Sie Schnittstellen mit get / set-Methoden oder -Eigenschaften in Betracht, wie z Art von Hiearchies.
quelle
Ist das nicht was für Schnittstellen sind? Nicht verwandte Klassen mit unterschiedlichen Funktionen, jedoch mit einer ähnlichen Eigenschaft.
quelle
Ihre Frage scheint im Kontext einer Sprache umrahmt zu sein, die Mehrfachvererbung nicht unterstützt, dies jedoch nicht speziell spezifiziert. Wenn Sie mit einer Sprache arbeiten, die Mehrfachvererbung unterstützt, ist dies mit nur einer einzigen Vererbungsebene trivial einfach zu lösen.
Hier ist ein Beispiel, wie dies durch Mehrfachvererbung gelöst werden kann.
quelle