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