Инъекция зависимости приводит к разрастанию фабрик?

Я всегда чувствовал себя некомфортно при работе с классами, которые должны были создавать экземпляры многих объектов, так как я использовал принципы инъекции зависимостей.

например, предположим, у меня есть класс, который должен вызывать много разных событий. Каждое событие имеет другой тип, поэтому я бы сделал другую фабрику для каждого другого типа события. Если у меня 10 мероприятий, то у меня должно быть 10 заводов. Это не кажется приятным. Я тоже мог бы одна фабрика для всех различных видов событий, но это также не кажется слишком правильным.

(для толпы C# я не говорю о событиях .NET здесь. Это был просто пример, чтобы добраться до сути, просто подумайте о них как о регулярных классах!)

Это был просто пример. У меня нет проблем с заводом здесь или там, но в некоторых проектах, где нужно создавать много объектов во время выполнения, кажется, что я должен сделать фабрику почти для каждого класс я определяю!

Как вы справляетесь с этой ситуацией? Я что-то упускаю?

Я видел, как люди просто передают ссылку на контейнер МОК, который они используют, но это не кажется мне хорошим. ИМО, модель домена даже не должна знать, что используется контейнер IoC!

спасибо

2 ответов


нет ничего плохого в классе, который создает экземпляры многих других объектов. Вместо этого этот класс следует рассматривать как совокупный корень сущности. Что касается разных" типов " сущности, если вы предполагаете, что они реализуют один и тот же интерфейс или наследуют один и тот же базовый класс, то передайте до Factory.create(type) Как я обычно подхожу к этой проблеме. Внутренности create() может делегировать другим классам ala шаблон стратегии, но клиент сталкивается API прост.

теперь, если вы создаете фабрику для каждого класса, с которым имеете дело, это звучит как-то анти-шаблон. Изучите совокупный корневой шаблон, упомянутый выше, и посмотрите, можете ли вы организовать свои сущности в графики - вы должны быть в состоянии - так, чтобы одной фабрики было достаточно для генерации всего графика.

Что касается IoC, модель домена не должна знать о контейнере. Когда у меня есть сущности, которым нужны ссылки на singletons - обычно фабрики - в контейнере я обычно впрыскиваю одну фабрику в другую как таковую:

class FactoryA {
    void setFactoryB(FactoryB factoryB) { /* sets into state */ }
    EntityA create(Enum type) {
        EntityA entityA = new EntityA();
        /* DI FactoryB - this method is probably default access */
        entityA.setFactoryB(getFactoryB());
    }
}

class FactoryB {}

так, в приведенном выше примере оба FactoryA и FactoryB являются синглетами, управляемыми контейнером IoC. EntityA нуждается в ссылке на FactoryB, так что FactoryA вводится со ссылкой на FactoryB это прошло внутри create() метод.


Я был поклонником инъекции конструктора так долго, как я знал о DI, потому что, на мой взгляд, это то, что конструктор на. В нем говорится: "мне нужны экземпляры следующих классов / интерфейсов для выполнения моей работы" - например, передайте мне File и PrintWriter и я напишу содержание первого ко второму.

и, конечно, это означает, что код не знает о структуре DI, так как класс просто строится с его требуемым зависимости переданы. Кроме того, я не вижу необходимости в фабриках в этом сценарии, так как класс является собственной фабрикой через конструктор.


Что касается сценария, который вы определили во втором абзаце, я не уверен, что это строго связано с инъекцией зависимостей, а просто дизайном иерархии классов и обязанностей. или ваш класс знает, как создать Event что соответствует, например, неудачного входа в в каком случае он это делает (т. е. вызывая конструктор класса);или, он не знает, как, в этом случае ему придется делегировать некоторые вид фабрики для создания Event.

и в этом случае вы можете настроить свой класс на использование одной и той же фабрики для создания всех десяти событий (определите EventFactory интерфейс с 10 методами), или вы можете определить отдельный интерфейс фабрики (& реализация) для каждого типа события, которое нуждается в contructing. В этом в последнем случае вам также нужно будет пройти десять разных фабрик в конструкторе вашего основного класса.

но опять же-это не имеет ничего общего с Ди ИМХО, это вопрос о том, как вы разрабатываете свои классы для гибкости (или "предприимчивости") против прямолинейности. На мой взгляд, они ортогональны; сначала вы определяете, какие сотрудники нужны вашему классу (десять фабрик, одна фабрика или ноль фабрик) и затем вы используете DI для предоставления этих зависимостей. Присутствие или в противном случае не должны влиять на ваш дизайн класс.