Stackoverflowers!
Я недавно начал баловаться с Ruby, и у меня есть несколько вопросов.Сначала немного предыстории: я привык к наследованию C ++ и Java и всегда испытывал неприязнь к тому, как там работает наследование во многих игровых сценариях (например, в стиле roguelike).Главным образом из-за того, что трудно хорошо описать поведение.Например, в Java: (не то, чтобы я реализовал это таким образом, но это был лучший пример, который я мог предложить в короткие сроки.)
Actor extends GameObject
Creature extends Actor
FlyingCreature extends Creature
Dragon extends FlyingCreature
Humanoid extends Creature
... пока все хорошо,право?Но что, если я решил реализовать класс «Горгулья» (крылатый гуманоид)?Тогда он будет принадлежать как FlyingCreature, так и Humanoid - поэтому мне придется заключить в капсулу одну из черт, а затем рефакторировать ее или что-то в этом роде.
Идеальное решение - лично - было бы, если бы были какие-то эффективныеспособ извлечения уникальных атрибутов / функциональных возможностей в инкапсулированные объекты, а затем каждый GameObject представляет собой композицию из различных модульных компонентов, которые могут взаимодействовать друг с другом.(Без наследования, кроме событий, таких как Item: GameObject, Actor: GameObject, Tile: GameObject - если даже тогда).
Так что определенный GameObject (скажем, орк) может быть легко создан путем созданиядерево компонентов - что-то вроде этого, но более гибкое:
[Actor]
[Organic]/ | \[Persona] // Name, etc..
| \
[Humanoid] [Intelligence] // AI or PlayerController
|
[Inventory] // [ArrayList of items...]
|
[Equipment] // [Hash of :slot -> Item]
Но более важно: когда я начал изучать Ruby, я узнал о его возможностях метапрограммирования, его свободе во время выполнения благодаряотражение языка и возможности расширения / включения модулей.Поэтому я решил, что если бы я разделил определенные черты на модули (и удостоверился, что у них есть осторожные политики именования и тому подобное), то я мог бы позволить своим классам включать поведение в соответствии с контекстом и событиями.Например, допустим, у меня есть гном по имени Боб О'Копп, и он спотыкается о крошечного поросёнка-вампира, в то же время разговаривая в темной канализационной темнице.И, таким образом, он попадает в какую-то магическую лужу, которая его мутирует, давая ему милые сказочные крылья.Но так как гномы обычно не птичьи, его класс не обладает функциональностью полета.Но для этого случая это была бы действительная черта.Таким образом, я подумал, что «полет bob.extend» будет отличным решением проблемы.
Но что, если одна из черт является временной?Допустим, Боб О'Копп находит свиток, который вызывает магические крылья на спине на время действия заклинания ... Но.После долгих поисков я еще не нашел какой-либо хорошей информации о том, как убирать / расширять или исключать миксины после его применения - если это вообще возможно.И поскольку здесь много действительно умных и опытных программистов, я бы хотел официально попросить вас поделиться с вами великолепной проницательностью, о могучие бородатые оракулы!: -)
Итак ... несколько вопросов:
- Бреду ли я, что хочу использовать миксин таким образом?
- Есть ли у меня большой недостаток?не задумывались?
- Можно ли вообще отозвать миксин после его применения?
- Есть ли у вас какие-либо другие рекомендации для хорошего способа решения проблемы?(достаточно указать мне направление в виде некоторых ключевых слов)
С нетерпением ожидая любых ответов с ожиданием
Огромное спасибо заранее,
-Robocopulate