Внедрение зависимостей в сравнении с шаблоном фабрики - PullRequest
463 голосов
/ 17 февраля 2009

Большинство примеров, приведенных для использования Dependency Injection, мы также можем решить, используя фабричный шаблон. Похоже, что когда дело доходит до использования / дизайна, разница между внедрением зависимости и фабрикой размыта или тонка.

Однажды кто-то сказал мне, что то, как вы его используете, имеет значение!

Однажды я использовал StructureMap контейнер DI для решения проблемы, позже я переработал его для работы с простой фабрикой и удалил ссылки на StructureMap.

Может кто-нибудь сказать мне, в чем разница между ними и где что использовать, какова лучшая практика здесь?

Ответы [ 27 ]

6 голосов
/ 28 августа 2011

МОК - это концепция, которая реализуется двумя способами. Создание зависимости и внедрение зависимости. Фабрика / Абстрактная фабрика являются примером создания зависимости. Внедрение зависимостей - это конструктор, установщик и интерфейс. Суть IOC состоит в том, чтобы не зависеть от конкретных классов, но определить реферат методов (скажем, интерфейс / абстрактный класс) и использовать этот реферат для вызова метода конкретного класса. Как и фабричный шаблон, возвращают базовый класс или интерфейс. Подобное внедрение зависимостей использует базовый класс / интерфейс для установки значения для объектов.

5 голосов
/ 17 февраля 2009

С внедрением зависимостей клиенту не нужно получать свои зависимости самостоятельно, все подготовлено заранее.

На фабриках кто-то должен вызывать их, чтобы доставить сгенерированные объекты туда, где они нужны.

Разница заключается в основном в этой строке, где выполняется вызов фабрики и выборка созданного объекта.

Но на фабриках вы должны написать эту 1 строку везде, где вам нужен такой объект. С DI вам просто нужно создать разводку (отношение между использованием и созданным объектом) один раз и просто полагаться на присутствие объекта впоследствии везде. С другой стороны, DI часто требует немного больше (насколько это зависит от структуры) работы на стороне подготовки.

3 голосов
/ 14 января 2015

Вы можете взглянуть на эту ссылку для сравнения двух (и других) подходов в реальном примере.

В основном, когда требования меняются, вы в конечном итоге модифицируете больше кода, если используете фабрики вместо DI.

Это также верно для ручного DI (т. Е. Когда нет внешней среды, предоставляющей зависимости вашим объектам, но вы передаете их в каждом конструкторе).

3 голосов
/ 21 декабря 2010

У меня был тот же вопрос, как только я прочитал о DI и оказался на этом посту. Итак, наконец, это то, что я понял, но, пожалуйста, поправьте меня, если я ошибаюсь.

"Давным-давно существовали маленькие королевства со своими собственными руководящими органами, контролирующими и принимающими решения на основе своих собственных письменных правил. Позже сформировалось большое правительство, исключающее все эти маленькие руководящие органы, которое имеет один набор правил (конституцию) и реализуется через суды "

Руководящие органы маленьких королевств - "Фабрики"

Большое правительство - «Инъектор зависимости».

2 голосов
/ 17 февраля 2009

Я считаю, что DI - это способ конфигурирования или создания экземпляра бина. DI можно сделать разными способами, такими как конструктор, сеттер-геттер и т. Д.

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

Проверьте эту ссылку: Внедрение зависимостей

2 голосов
/ 17 февраля 2009

Binoj,

Я не думаю, что вам нужно выбирать одно над другим.

Действие по перемещению зависимого класса или интерфейса в конструктор или установщик класса следует шаблону DI. Объект, который вы передаете конструктору или множеству, может быть реализован с помощью Factory.

Когда использовать? Используйте шаблон или шаблоны, которые есть в вашей рубке разработчика. Что они чувствуют себя наиболее комфортно и легче всего понять?

2 голосов
/ 28 апреля 2017

Я полагаю, 3 важных аспекта управляют объектами и их использованием:
1. Реализация (класса вместе с инициализацией, если есть).
2. Инъекция (созданного таким образом экземпляра), где это необходимо.
3. Управление жизненным циклом (созданного экземпляра).

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

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

В то время как фабрики могут подходить для небольших применений, для крупных лучше выбирать DI, чем фабрики.

1 голос
/ 31 марта 2016

По номиналу они выглядят одинаково

Проще говоря, Factory Pattern, Creational Pattern помогает создать нам объект - «Определить интерфейс для создания объекта». Если у нас есть ключевое значение пула объектов (например, словарь), передав ключ к фабрике (я имею в виду простой шаблон фабрики), вы можете разрешить тип. Работа выполнена! С другой стороны, структура внедрения зависимостей (например, Structure Map, Ninject, Unity и т. Д.), Похоже, делает то же самое.

Но ... "Не изобретай велосипед"

С архитектурной точки зрения это связующий слой и «Не изобретай велосипед».

Для приложения корпоративного уровня концепция DI - это скорее архитектурный уровень, который определяет зависимости. Чтобы еще больше упростить это, вы можете думать об этом как об отдельном библиотечном проекте, который разрешает зависимости. Основное приложение зависит от этого проекта, где решатель зависимостей относится к другим конкретным реализациям и разрешению зависимостей.

В дополнение к «GetType / Create» из Фабрики, чаще всего нам нужны дополнительные функции (возможность использовать XML для определения зависимостей, макетирование и модульное тестирование и т. Д.). Поскольку вы ссылались на Карту структуры, посмотрите список функций Карта структуры . Это явно больше, чем просто разрешение простого сопоставления объектов. Не изобретай велосипед!

Если у вас есть только молоток, все выглядит как гвоздь

В зависимости от ваших требований и типа создаваемого приложения вам необходимо сделать выбор. Если в нем всего несколько проектов (может быть один или два ...) и в нем мало зависимостей, вы можете выбрать более простой подход. Это похоже на использование доступа к данным ADO .Net по сравнению с использованием Entity Framework для простых вызовов базы данных 1 или 2, где внедрение EF в этом случае является излишним.

Но для более крупного проекта или если ваш проект становится больше, я бы настоятельно рекомендовал иметь слой DI с каркасом и освободить место для изменения используемой вами структуры DI (используйте фасад в основном приложении (Web App, Web Api, рабочий стол .. и т. Д.).

1 голос
/ 17 июня 2013

Injection Framework - это реализация фабричного шаблона.

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

Вы должны развертывать свое собственное решение, только если ваши требования не могут быть выполнены какой-либо из сторонних платформ. Чем больше кода вы пишете, тем больше кода вы должны поддерживать. Кодекс является обязательством, а не активом.

Аргументы относительно того, какую реализацию вы должны использовать, не так важны, как понимание архитектурных потребностей вашего приложения.

1 голос
/ 24 сентября 2014

Шаблон дизайна фабрики

Шаблон проектирования фабрики характеризуется

  • Интерфейс
  • Классы реализации
  • фабрика

Вы можете наблюдать несколько вещей, когда задаете себе вопрос, как показано ниже

  • Когда фабрика создаст объект для классов реализации - время выполнения или время компиляции?
  • Что если вы хотите переключить реализацию во время выполнения? - Не возможно

Они обрабатываются инъекцией зависимостей.

Зависимость инъекций

Вы можете по-разному вводить зависимость. Для простоты пойдем с интерфейсом впрыска

В DI контейнер создает необходимые экземпляры и «внедряет» их в объект.

Таким образом устраняется статическая реализация.

Пример:

public class MyClass{

  MyInterface find= null;

  //Constructor- During the object instantiation

  public MyClass(MyInterface myInterface ) {

       find = myInterface ;
  }

  public void myMethod(){

       find.doSomething();

  }
}
...