Есть SE проект - плагин для одного приложения. В нем есть много классов-менеджеров: CommandManager, EntityManager, RestoreManager и так далее. Все эти менеджеры отвечают за разные вещи и могут использоваться в различных частях программы - как в других менеджерах, так и в остальных классах, которые от них зависимы. Вообще, в системе должно существовать по одному инстансу такого менеджера.
Большинство менеджеров зависят друг от друга, также многие из них зависят от инстанса плагина - PluginInstance. От остальных классов системы они не зависят.
Вопрос в том, как грамотно организовать доступ к объектам-менеджерам . Мои варианты:
1. Самое первое, что приходит в голову - синглтоны. Для каждого менеждера делаем статический геттер и обращаемся к нему откуда угодно. Правда, ленивая инициализация подойдет
не для всех менеджеров - некоторые нужно явно загрузить при старте и запустить выполнение некоторых задач, но это уже не так страшно. В общем, если полностью перевести систему
на синглтоны: сделать ими и менеджер, и сам плагин, то проблема в итоге разрешается. Вопрос в том, насколько это грамотное решение, когда весь проект будет пестрить getInstance-ми.
2. Dependency Injection. Передавать классам через конструкторы менеджеров, которые им нужны. Здесь проблема в том, что некоторые классы порождаются не там, где создаются инстансы менеджеров,
поэтому в отдельных случаях объекты менеджеров придется "тащить" через 2-3 класса, и такая структура будет очень громоздкой. Как вариант - инжектить поля рефлексивно, но в интернете пишут о том,
что это ужасная практика (хотя, насколько я понимаю, в том же спринге она вполне себе применяется).
3. Создать класс, который просто будет держать ссылки на все существующие в системе менеджеры. Назвать как-нибудь вроде Core, System. В нем будут методы getCommandManager(), getEntityManager(), getRestoreManager() и т.д.
Теперь вместо N объектов менеджеров нам достаточно протащить во все классы ссылку на System или вовсе сделать System синглтоном. Впрочем, здесь
уже неважно, поскольку у нас в итоге получается одна ссылка вместо 10, и организовать к ней доступ уже явно не проблема.
Итак, как будет правильней организовать такую систему зависимостей? Возможно, есть еще варианты?
Начать с третьего варианта, назвать этот класс СпрингКонтекст. Все инициализировать через конструкторы беря инстансы из контекста, тогда ты увидишь циклические зависимости если они есть. В качестве хака для циклических зависимостей будешь передавать их через set метод.