Резюме
В течение последних нескольких месяцев я программировал легкий игровой движок на основе C #с абстракцией API и системой сущностей/компонентов/скриптов.. Вся его идея состоит в том, чтобы упростить процесс разработки игр в XNA, SlimDX и т. д., предоставляя архитектуру, аналогичную той, что используется в движке Unity.
Проблемы дизайна
Как известно большинству разработчиков игр, существует множество различных сервисов, к которым нужно обращаться по всему коду.Многие разработчики прибегают к использованию глобальных статических экземпляров, например. Менеджер рендеринга (или композитор ), Сцена, Графическое устройство (DX ), Регистратор, Состояние ввода, Область просмотра, Окно и так далее. Есть несколько альтернативных подходов к глобальным статическим экземплярам/одиночкам. Один из них — предоставить каждому классу экземпляр классов, к которым ему нужен доступ, либо через конструктор, либо через внедрение зависимостей конструктора/свойства (DI ), другой — использовать глобальный локатор службы, такой как ObjectFactory StructureMap, где локатор службы обычно настраивается как контейнер IoC.
Внедрение зависимостей
Я выбрал DI по многим причинам. Наиболее очевидным из них является тестируемость за счет программирования для интерфейсов и наличия всех зависимостей каждого класса, предоставляемых им через конструктор. Эти классы легко тестируются, поскольку тестовый контейнер может создавать экземпляры необходимых служб или их макеты и подавать в каждый класс для тестирования. Еще одной причиной использования DI/IoC было, хотите верьте, хотите нет, повысить читабельность кода. Больше нет громоздкого процесса инициализации, когда создаются экземпляры всех различных сервисов и вручную создаются экземпляры классов со ссылками на требуемые сервисы. Настройка ядра (NInject )/Registry (StructureMap )удобно предоставляет единую точку конфигурации для движка/игры, где выбираются и настраиваются реализации сервисов.
Мои проблемы
В основном выполнение DI/IoC резко снижает мою производительность и в некоторых случаях еще больше усложняет код и архитектуру. Поэтому я не уверен, должен ли я следовать этому пути или просто сдаюсь и делаю все по старинке. Я не ищу единого ответа, говорящего, что я должен или не должен делать, но обсуждение того, стоит ли использовать DI в долгосрочной перспективе, в отличие от использования глобального статического/одиночного способа, возможные плюсы и минусы, которые я упустил из виду, и возможные решения моих проблем, перечисленных выше, при работе с DI.