Инъекция зависимости приводит к разрастанию фабрик?
Я всегда чувствовал себя некомфортно при работе с классами, которые должны были создавать экземпляры многих объектов, так как я использовал принципы инъекции зависимостей.
например, предположим, у меня есть класс, который должен вызывать много разных событий. Каждое событие имеет другой тип, поэтому я бы сделал другую фабрику для каждого другого типа события. Если у меня 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 для предоставления этих зависимостей. Присутствие или в противном случае не должны влиять на ваш дизайн класс.