Ich habe eine Anwendung, die auf Squeryl basiert. Ich definiere meine Modelle als Fallklassen, vor allem, weil ich Kopiermethoden für zweckmäßig halte.
Ich habe zwei Modelle, die eng miteinander verbunden sind. Die Felder sind gleich, viele Operationen sind gemeinsam und sie sollen in derselben DB-Tabelle gespeichert werden. Es gibt jedoch ein Verhalten, das nur in einem der beiden Fälle Sinn macht oder in beiden Fällen Sinn macht, aber unterschiedlich ist.
Bisher habe ich nur eine einzige Fallklasse verwendet, mit einem Flag, das den Typ des Modells unterscheidet, und alle Methoden, die sich je nach Typ des Modells unterscheiden, beginnen mit einem if. Das ist nervig und nicht ganz typsicher.
Was ich tun möchte, ist, das allgemeine Verhalten und die Felder in einer Ahnenfallklasse zu berücksichtigen und die beiden tatsächlichen Modelle davon erben zu lassen. Soweit ich weiß, ist das Erben von Fallklassen in Scala verpönt und sogar verboten, wenn die Unterklasse selbst eine Fallklasse ist (nicht mein Fall).
Was sind die Probleme und Fallstricke, die ich beim Erben von einer Fallklasse beachten sollte? Ist es in meinem Fall sinnvoll, dies zu tun?
quelle
Antworten:
Meine bevorzugte Methode zur Vermeidung der Vererbung von Fallklassen ohne Codeduplizierung liegt auf der Hand: Erstellen Sie eine gemeinsame (abstrakte) Basisklasse:
Wenn Sie feinkörniger sein möchten, gruppieren Sie die Eigenschaften in einzelne Merkmale:
quelle
Da dies für viele ein interessantes Thema ist, möchte ich hier etwas Licht ins Dunkel bringen.
Sie könnten mit dem folgenden Ansatz gehen:
Ja, Sie müssen die Felder duplizieren. Wenn Sie nicht tun, wäre es einfach nicht möglich, korrekte Gleichheit zu implementieren unter anderem Probleme .
Sie müssen jedoch keine Methoden / Funktionen duplizieren.
Wenn die Duplizierung einiger Eigenschaften für Sie so wichtig ist, verwenden Sie reguläre Klassen, aber denken Sie daran, dass sie nicht gut zu FP passen.
Alternativ können Sie Komposition anstelle von Vererbung verwenden:
Komposition ist eine gültige und solide Strategie, die Sie ebenfalls berücksichtigen sollten.
Und falls Sie sich fragen, was ein versiegeltes Merkmal bedeutet - es kann nur in derselben Datei erweitert werden. Das heißt, die beiden oben genannten Fallklassen müssen sich in derselben Datei befinden. Dies ermöglicht umfassende Compilerprüfungen:
Gibt einen Fehler:
Welches ist wirklich nützlich. Jetzt werden Sie nicht vergessen, sich mit den anderen Arten von
Person
s (Menschen) zu befassen . Dies ist im Wesentlichen das, was dieOption
Klasse in Scala tut.Wenn Ihnen das nichts ausmacht, können Sie es nicht versiegeln und die Fallklassen in ihre eigenen Dateien werfen. Und vielleicht mit Komposition gehen.
quelle
def name
in der Eigenschaft sein mussval name
. Mein Compiler gab mir mit dem ersteren nicht erreichbare Code-Warnungen.case-Klassen eignen sich perfekt für Wertobjekte, dh Objekte, die keine Eigenschaften ändern und mit Gleichheitswerten verglichen werden können.
Die Implementierung von Gleichheit bei vorhandener Vererbung ist jedoch ziemlich kompliziert. Betrachten Sie zwei Klassen:
und
Entsprechend der Definition sollte der Farbpunkt (1,4, rot) gleich dem Punkt (1,4) sein, sie sind schließlich der gleiche Punkt. ColorPoint (1,4, blau) sollte also auch gleich Punkt (1,4) sein, oder? Aber natürlich sollte ColorPoint (1,4, rot) nicht gleich ColorPoint (1,4, blau) sein, da sie unterschiedliche Farben haben. Los geht's, eine grundlegende Eigenschaft der Gleichheitsrelation ist gebrochen.
aktualisieren
Sie können die Vererbung von Merkmalen verwenden, um viele Probleme zu lösen, wie in einer anderen Antwort beschrieben. Eine noch flexiblere Alternative ist häufig die Verwendung von Typklassen. Siehe Wofür sind Typklassen in Scala nützlich?oder http://www.youtube.com/watch?v=sVMES4RZF-8
quelle
Employer.fire(e: Emplooyee)
aber nicht umgekehrt. Ich würde gerne zwei verschiedene Klassen machen, da sie tatsächlich verschiedene Objekte darstellen, aber ich mag auch nicht die Wiederholung, die entsteht.In diesen Situationen tendiere ich dazu, Komposition anstelle von Vererbung zu verwenden, dh
Natürlich können Sie eine komplexere Hierarchie und Übereinstimmungen verwenden, aber hoffentlich erhalten Sie eine Idee. Der Schlüssel besteht darin, die verschachtelten Extraktoren zu nutzen, die Fallklassen bereitstellen
quelle