Абстрактный образец factory поверх IoC?
Я решил использовать принципы IoC в более крупном проекте. Тем не менее, я хотел бы получить что-то прямое, что беспокоило меня в течение длительного времени. Вывод, который я придумал, заключается в том, что контейнер IoC является архитектурным шаблоном, а не шаблоном проектирования. Другими словами, ни один класс не должен знать о его присутствии, и сам контейнер должен использоваться на уровне приложения, чтобы сшить все компоненты. По существу, он становится опцией, на вершине хорошо продуманной объектно-ориентированной модели.
Сказав это, как можно получить доступ к разрешенным типам без разбрызгивания контейнеров IoC по всему месту (независимо от того, они абстрагированы или нет)? Единственный вариант, который я вижу здесь, - использовать абстрактные фабрики, которые используют контейнер IoC для разрешения конкретных типов. Это должно быть достаточно просто, чтобы поменяться местами для набора стандартных фабрик. Это хороший подход? Кто-нибудь здесь использовал его и насколько хорошо он работал на вас? Есть ли что-нибудь еще?
Спасибо!
Ответы
Ответ 1
Как вы уже выяснили, сама инжекция зависимостей (DI) сама по себе является лишь набором шаблонов и методов.
В корне приложения мы подключаем все необходимые графы объектов. Это место называется Root, и мы можем использовать контейнер DI для выполнения этой проводки для нас, или мы можем сделать это вручную (Poor Man DI).
Дело в том, что в вашем приложении есть только одно место, где есть сильная ссылка на конкретную технологию (ваш контейнер DI). Остальная часть приложения блаженно не знает о том, как был привязан граф объекта - все, что имеет значение, - это то, что все необходимые зависимости были правильно введены (и вы можете использовать Инъекция конструктора с Null Guard, чтобы гарантировать, что это так).
Образец Аннотация Factory - очень полезный образец, когда дело доходит до DI. По сути, используйте Abstract Factory, когда:
- Вам нужно указать один или несколько параметров, известных только во время выполнения, прежде чем вы сможете разрешить зависимость.
- Время жизни зависимостей концептуально короче, чем время жизни потребителя.
Примеры и дополнительная информация доступны здесь:
Ответ 2
В верхней части большей части вашего приложения вам понадобится класс Bootstrap, который загружает контекст IOC. Этот контекст затем предоставит фактически созданные объекты и, следовательно, будет действовать как factory.
Но это должно происходить только с очень небольшим количеством объектов, и пользователь вашего класса Bootstrap/ Factory должен знать как можно меньше о базовой архитектуре. Например, если вы полностью сконфигурировали объект HTTP-сервера через IOC, и вы хотите запустить его, ваш класс Bootstrap должен только предоставить метод getHttpServer(). Тогда вашему основному методу программы нужно только вызвать Bootstrap.getHttpServer(). Start(), чтобы запустить его.
Проводка ваших других объектов уже была выполнена с помощью контекста приложения, например. вы настраиваете объект A через IOC, который является частью объекта B, поэтому вы настраиваете объект B со ссылкой на объект A. Ни один из них обычно не должен знать ни о контейнере, ни о factory.