Antecedentes
Aquí está el problema real en el que estoy trabajando: quiero una forma de representar cartas en el juego de cartas Magic: The Gathering . La mayoría de las cartas en el juego son cartas de aspecto normal, pero algunas de ellas están divididas en dos partes, cada una con su propio nombre. Cada mitad de estas tarjetas de dos partes se trata como una tarjeta en sí. Entonces, para mayor claridad, usaré Card
solo para referirme a algo que sea una tarjeta regular o la mitad de una tarjeta de dos partes (en otras palabras, algo con un solo nombre).
Entonces tenemos un tipo base, Card. El propósito de estos objetos es realmente mantener las propiedades de la tarjeta. Realmente no hacen nada por sí mismos.
interface Card {
String name();
String text();
// etc
}
Hay dos subclases de Card
, que estoy llamando PartialCard
(la mitad de una tarjeta de dos partes) y WholeCard
(una tarjeta normal). PartialCard
tiene dos métodos adicionales: PartialCard otherPart()
y boolean isFirstPart()
.
Representantes
Si tengo un mazo, debería estar compuesto de WholeCard
s, no de Card
s, como a Card
podría ser un PartialCard
, y eso no tendría sentido. Entonces, quiero un objeto que represente una "tarjeta física", es decir, algo que pueda representar uno WholeCard
o dos PartialCard
s. Estoy tentativamente llamando a este tipo Representative
, y Card
tendría el método getRepresentative()
. A Representative
casi no proporcionaría información directa sobre las tarjetas que representa, solo las señalaría. Ahora, mi idea brillante / loca / tonta (usted decide) es que WholeCard hereda de ambos Card
y Representative
. Después de todo, ¡son cartas que se representan a sí mismas! WholeCards podría implementarse getRepresentative
como return this;
.
En cuanto a PartialCards
, no se representan a sí mismos, pero tienen un externo Representative
que no es un Card
, pero proporciona métodos para acceder a los dos PartialCard
s.
Creo que esta jerarquía de tipos tiene sentido, pero es complicada. Si pensamos en Card
s como "tarjetas conceptuales" Representative
ys como "tarjetas físicas", bueno, ¡la mayoría de las tarjetas son ambas! Creo que podría argumentar que las tarjetas físicas de hecho contienen tarjetas conceptuales y que no son lo mismo , pero diría que lo son.
Necesidad de fundición de tipo
Debido a que PartialCard
sy WholeCards
son ambos Card
, y generalmente no hay una buena razón para separarlos, normalmente solo estaría trabajando con ellos Collection<Card>
. Así que a veces necesito lanzar PartialCard
s para acceder a sus métodos adicionales. En este momento, estoy usando el sistema descrito aquí porque realmente no me gustan los moldes explícitos. Y Card
, como , Representative
necesitaría ser lanzado a a WholeCard
o Composite
, para acceder a los Card
s reales que representan.
Así que solo para resumen:
- Tipo base
Representative
- Tipo base
Card
- Tipo
WholeCard extends Card, Representative
(no se necesita acceso, se representa a sí mismo) - Tipo
PartialCard extends Card
(da acceso a otra parte) - Tipo
Composite extends Representative
(da acceso a ambas partes)
¿Esto es una locura? Creo que en realidad tiene mucho sentido, pero honestamente no estoy seguro.