Абстрактный фабричный шаблон поверх IoC?

Я решил использовать принципы IoC в более крупном проекте. Тем не менее, я хотел бы получить что-то прямо, что беспокоило меня в течение длительного времени. Я пришел к выводу, что контейнер IoC - это архитектурный шаблон, а не шаблон проектирования. Другими словами, ни один класс не должен знать о своем присутствии, и сам контейнер должен использоваться на прикладном уровне для объединения всех компонентов. По сути, это становится опцией, поверх хорошо разработанной объектно-ориентированной модели. Сказав это, как можно получить доступ к разрешенным типам, не разбрасывая контейнеры IoC повсюду (независимо от того, являются ли они абстрактными или нет)? Единственный вариант, который я вижу здесь, - это использование абстрактных фабрик, которые используют контейнер IoC для разрешения конкретных типов. Это должно быть достаточно легко, чтобы заменить набор стандартных фабрик. Это хороший подход? Кто-нибудь здесь использовал это и насколько хорошо он работал для вас? Есть ли что-нибудь еще доступное?

Спасибо!

2 ответа

Решение

Как вы уже поняли, сам по себе Dependency Injection (DI) - это всего лишь набор шаблонов и техник.

В корне приложения мы подключаем все необходимые графы объектов. Это место называется Composition Root, и мы можем использовать DI-контейнер для этой проводки за нас, или мы можем сделать это вручную ( Pure DI).

Дело в том, что в вашем приложении есть только одно место, где есть четкая ссылка на конкретный элемент технологии (ваш DI-контейнер). Остальная часть приложения, к счастью, не знает, как был построен объектный граф - все, что имеет значение, это то, что все необходимые зависимости были правильно введены (и вы можете использовать Constructor Injection с Null Guards, чтобы гарантировать, что это так).

Шаблон Abstract Factory - очень полезный шаблон, когда дело доходит до DI. По сути, используйте Abstract Factory, когда:

  • Вам нужно указать один или несколько параметров, известных только во время выполнения, прежде чем вы сможете разрешить зависимость.
  • Время существования зависимости концептуально короче, чем время жизни потребителя.

Примеры и дополнительная информация доступна здесь:

В верхней части вашего приложения вам понадобится класс Bootstrap, который загружает контекст IOC. Этот контекст затем предоставит фактически созданные объекты и, следовательно, действует как фабрика.

Но это должно происходить только с очень небольшим количеством объектов, и пользователь вашего класса Bootstrap/Factory должен знать как можно меньше об основной архитектуре. Например, если вы полностью сконфигурировали объект HTTP-сервера через IOC и хотите запустить его, ваш класс Bootstrap должен только предоставить метод getHttpServer(). Тогда вашему методу main необходимо только вызвать Bootstrap.getHttpServer(). Start(), чтобы запустить его.

Подключение других ваших объектов уже было выполнено контекстом приложения, например, вы конфигурируете объект A через IOC, который является частью объекта B, поэтому вы конфигурируете объект B со ссылкой на объект A. Обычно ни один из них не должен знать ни о контейнере ни заводской.

Другие вопросы по тегам