Наверное, выраженный одним предложением, вопрос звучит дико. Попробую сформулировать понятнее.
Игра разделена на некое подобие модели и представления. Имеется базовый класс для всех материальных объектов в игре: SpaceObject, у него есть наследники: Planet, Star, Ship, Asteroid и т.д.. Пока оно все "живет" внутри этой самой модели - все хорошо. Но как только возникает необходимость отобразить объект - появляются проблемы.
Итак, в случае, если объект появляется в одной локации с игроком (есть соответствующее событие), необходимо создать его "alter ego" в виде GameObject игрового движка. Проблема в таком коде:
void InitializeSpaceObject(SpaceObject spaceObject)
{
if (spaceObject is Star)
InitializeStar(spaceObject as Star);
else if (spaceObject is Planet)
InitializePlanet(spaceObject as Planet);
else if (spaceObject is AsteroidField)
InitializeAsteroidField(spaceObject as AsteroidField);
else
throw new UnknownSpaceObjectTypeException("Cannot initialize SpaceObject of type " + spaceObject.GetType().ToString() + ": unknown type.");
}
Понятное дело, такой код, как минимум, нарушает принцип подстановки Лисков, а вообще - просто неудобен в использовании и расширении. Но просто добавить ссылку на некий инициализатор объекта в классе SpaceObject нельзя - модель не должна ничего знать о движке и всей логики визуализации.
Как можно избавиться от этой вереницы if'ов или, по крайней мере, автоматизировать процесс поиска инициализатора для нужного типа объекта?
Ниже попробую изложить пару вариантов, которые мне пришли в голову - возможно они жизнеспособны?
1)Объявить таблицу "Тип" - "Инициализатор". Чему быть инициализатором - делегатом метода или полноценным классом, вопрос уже вторичный. Немного лучше, чем if'ы, но все равно как-то громоздко
2)Unity-стайл. Создать по обычному MonoBehaviour скрипту на каждый тип объекта. Каждый слушает событие появления объекта в локации. Внутри подписанного метода - одна проверка if (spaceObject is ThisScriptHandlingType) {код инициализации}. Что скажете про такой вариант?