Hintergrund
Hier ist das eigentliche Problem, an dem ich arbeite: Ich möchte eine Möglichkeit, Karten im Kartenspiel Magic: The Gathering darzustellen . Die meisten Karten im Spiel sind normal aussehende Karten, aber einige von ihnen sind in zwei Teile unterteilt, von denen jeder seinen eigenen Namen hat. Jede Hälfte dieser zweiteiligen Karten wird als Karte behandelt. Aus Gründen der Klarheit Card
beziehe ich mich nur auf eine Karte, die entweder eine normale Karte oder eine Hälfte einer zweiteiligen Karte ist (mit anderen Worten, etwas mit nur einem Namen).
Wir haben also einen Basistyp, Card. Der Zweck dieser Objekte besteht eigentlich nur darin, die Eigenschaften der Karte zu speichern. Sie machen nichts wirklich alleine.
interface Card {
String name();
String text();
// etc
}
Es gibt zwei Unterklassen Card
, die ich nenne PartialCard
(eine Hälfte einer zweiteiligen Karte) und WholeCard
(eine reguläre Karte). PartialCard
hat zwei zusätzliche Methoden: PartialCard otherPart()
und boolean isFirstPart()
.
Vertreter
Wenn ich ein Deck habe, sollte es aus WholeCard
s bestehen, nicht aus Card
s, wie es sein Card
könnte PartialCard
, und das würde keinen Sinn ergeben. Ich möchte also ein Objekt, das eine "physische Karte" darstellt, also etwas, das ein WholeCard
oder zwei PartialCard
s darstellen kann. Ich rufe diesen Typ vorläufig auf Representative
und Card
hätte die Methode getRepresentative()
. A Representative
würde fast keine direkten Informationen über die Karte (n) liefern, die es darstellt, es würde nur auf sie zeigen. Nun, meine geniale / verrückte / dumme Idee (Sie entscheiden) ist, dass WholeCard von beiden Card
und erbt Representative
. Immerhin sind sie Karten, die sich selbst darstellen! WholeCards könnten getRepresentative
als implementieren return this;
.
Was PartialCards
, Sie repräsentieren sich nicht, aber sie haben eine externe Representative
, auf dem eine nicht Card
, sondern stellt Methoden für den Zugriff auf die beiden PartialCard
s.
Ich denke, diese Typhierarchie ist sinnvoll, aber kompliziert. Wenn wir uns Card
s als "konzeptuelle Karten" und Representative
s als "physische Karten" vorstellen, dann sind die meisten Karten beides! Ich denke, Sie könnten argumentieren, dass physische Karten tatsächlich konzeptionelle Karten enthalten und dass sie nicht dasselbe sind , aber ich würde argumentieren, dass sie es sind.
Notwendigkeit des Schriftgusses
Weil PartialCard
s und WholeCards
beide Card
s sind und es normalerweise keinen guten Grund gibt, sie zu trennen, würde ich normalerweise nur damit arbeiten Collection<Card>
. Manchmal musste ich also PartialCard
s besetzen, um auf ihre zusätzlichen Methoden zugreifen zu können. Im Moment benutze ich das hier beschriebene System, weil ich explizite Casts nicht mag. Und wie Card
, Representative
müsste entweder a WholeCard
oder gegossen werden Composite
, um auf die tatsächlichen Card
s zuzugreifen, die sie darstellen.
Also nur zur Zusammenfassung:
- Basistyp
Representative
- Basistyp
Card
- Typ
WholeCard extends Card, Representative
(kein Zugriff erforderlich, er repräsentiert sich selbst) - Typ
PartialCard extends Card
(ermöglicht den Zugriff auf andere Teile) - Typ
Composite extends Representative
(ermöglicht den Zugriff auf beide Teile)
Ist das verrückt? Ich denke, es macht tatsächlich viel Sinn, aber ich bin mir ehrlich gesagt nicht sicher.