ArXen42
@ArXen42

Как избавиться от static классов игрового мира в проекте?

Доброго времени суток. В unity проекте есть игровой мир (список звездных систем, объектов в них, подсистема контроля ходов/игровой даты). Проблема в том, что сейчас он представлен несколькими static классами и это начало создавать проблемы (нет единообразной десериализации мира как объекта, невозможно выкинуть его на растерзание GC и создать новый без костыльной очистки всех членов этих классов, к тому же в редакторе unity они не очищаются при остановке Play Mode и в результате может быть непредсказуемое поведение unit-тестов, запускающихся в оставшемся игровом мире и т.д. и т.п.).
Разумеется, если взять и убрать static, будет вот так:
7ae9de139a6742d9b105c07f06b392a1.png

Создал WorldContext, закинул в него эти самые WorldCtl, StarSystems и т.д.. Вот только как теперь довести его до всей этой толпы желающих? Конечно, можно просто создать статическое поле вида CurrentWorldContext, благо одновременная симуляция нескольких миров вряд ли понадобится. Но все же тот факт, что сущности, логически относящиеся к другому миру, могут внезапно обратиться к текущему, не радует, костыль же. Передавать его в конструкторы всех-всех-всех... слишком много boilerplate, что тоже плохо, да и память почем зря расходуется.
Может быть уже есть известные пути решения этой проблемы?

Подумал над таким методом решения проблемы: ввести интерфейс с одним свойством
public interface IWorldContextProvider
{
	WorldContext WorldContext { get; }
}

И реализовывать его "по цепочке" (т.е., скажем, реализация этого свойства для оборудования корабля будет возвращать это же свойство родительского корабля и т.д.). Но может есть более простое решение?
  • Вопрос задан
  • 607 просмотров
Решения вопроса 1
zagayevskiy
@zagayevskiy
Android developer at Yandex
Ну, вообще, то что вы ищите, называется Dependency Injection(DI). Передача в конструкторы везде-везде-везде руками - это одна из реализаций, практически самая примитивная. Наверняка в Юнити есть более лучшие реализации, предлагаю погуглить самостоятельно.
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
TheTalion
@TheTalion
Проблема в том, что вы обращаетесь к объектам, которые еще не созданы (если убираете статику). Поэтому вам нужно создать объекты. Если настройки там стандартные, то можно их все в го какое-нибудь закинуть и потом оттуда брать, как уже созданный элемент, если настройки изменяемые, то вам стоит сделать методы для изменения и вызывать их в каком-нибудь апдейте.

Если просто: если объект находится на сцене до запуска игры, то он считается созданным - вам только его инстанс нужно передавать и дальше уже использовать по своему усмотрению.
Ответ написан
@Espleth
Как я понял у вас проблема в Static классах, по-моему вам поможет паттерн Singleton. То есть ваши классы не будут static (могут даже наследовать от MonoBehaviour), но будет переменная Instance, которая позволит обращаться к ним в статическом контексте. Этим паттерном тоже, конечно, злоупотреблять не стоит, но по-моему это будет относительно безболезненным выходом.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы