Фон
Ось актуальна проблема, над якою я працюю: я хочу, щоб представити карти в картковій грі Magic: The Gathering . Більшість карт у грі - це картки звичайного вигляду, але деякі з них розділені на дві частини, кожна зі своєю назвою. Кожна половина цих двоскладових карт трактується як сама картка. Тож для наочності я буду використовувати Cardлише для позначення того, що є або звичайною карткою, або половиною картки з двох частин (іншими словами, щось із лише одним ім’ям).

Отже, у нас є базовий тип, Card. Мета цих об'єктів насправді просто утримувати властивості картки. Вони насправді нічого не роблять самі.
interface Card {
String name();
String text();
// etc
}
Є два підкласи Card, які я дзвоню PartialCard(половина картки з двох частин) та WholeCard(звичайна картка). PartialCardмає два додаткові методи: PartialCard otherPart()і boolean isFirstPart().
Представники
Якщо у мене є колода, вона повинна складатися з WholeCards, а не Cards, як a Cardможе бути PartialCard, і це не мало б сенсу. Тому я хочу об'єкт, який представляє "фізичну карту", тобто те, що може представляти одну WholeCardчи дві PartialCardс. Я орієнтовно називаю цей тип Representativeі Cardмав би метод getRepresentative(). A Representativeне надає майже ніякої прямої інформації на картці (картках), яку вона представляє, вона вказувала б лише на неї / них. Тепер моя блискуча / божевільна / німа ідея (ви вирішите) полягає в тому, що WholeCard успадковує і те, Card і іншеRepresentative . Адже це картки, які представляють себе! WholeCards могли реалізувати getRepresentativeяк return this;.
Що стосується PartialCards, вони не представляють себе, але у них є зовнішній, Representativeякий не є Card, але надає методи доступу до двох PartialCards.
Я думаю, що ієрархія цього типу має сенс, але вона складна. Якщо ми думаємо про Cards як "концептуальні карти", а Representatives - як "фізичні картки", то більшість карток є обома! Я думаю, ви можете зробити аргумент, що фізичні картки насправді містять концептуальні картки, і що вони не те саме , але я б стверджував, що вони є.
Необхідність типового лиття
Оскільки PartialCards і WholeCardsобидва Cards, і зазвичай немає вагомих причин відокремлювати їх, я зазвичай просто працюю Collection<Card>. Тому іноді мені потрібно буде робити це PartialCard, щоб отримати доступ до їх додаткових методів. Зараз я використовую описану тут систему, тому що я дійсно не люблю явні касти. І як Card, Representativeбуло б потрібно бути відлиті або до WholeCardабо Composite, щоб отримати доступ до фактичної CardS , які вони представляють.
Тож просто для підсумків:
- Тип бази
Representative - Тип бази
Card - Тип
WholeCard extends Card, Representative(доступ не потрібен, він представляє себе) - Введіть
PartialCard extends Card(надає доступ до іншої частини) - Тип
Composite extends Representative(надає доступ до обох частин)
Це божевільно? Я думаю, що це насправді має багато сенсу, але я, чесно кажучи, не впевнений.