Зачем нам нужны фреймворки для внедрения зависимостей? [закрыто]

42

Я читал больше о принципах Inversion of Control и Inpendency Injection как его реализации, и я уверен, что понимаю его.

Кажется, что в основном говорится «не объявляйте инстанцирования ваших учеников внутри класса». Скорее, что экземпляры должны быть переданы и назначены через конструктор; «введен» в класс из внешнего источника.

Если это так просто, как кажется, зачем нам нужны такие фреймворки, как spring или guice, которые реализуют это с аннотациями? Я что-то упустил здесь? Я действительно изо всех сил пытаюсь понять, что такое использование платформ Dependency Injection.

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

timsworth
источник
11
Они полезны для переноса ошибок во время выполнения вместо времени компиляции.
День
1
@den Зачем нам это делать? Это, кажется, нарушает неудачу быстро
Этому ПОЛЬЗОВАТЕЛЮ НУЖНА ПОМОЩЬ

Ответы:

26

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

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

Кроме того, платформы часто содержат другие полезные функции. Например, Spring содержит полезную среду для аспектно-ориентированного программирования, включая декларативное разграничение транзакций (что очень удобно) и множество реализаций адаптера, которые облегчают интеграцию многих сторонних библиотек.

Жюль
источник
8
Попал в самую голову. Нам они не нужны. Они просто облегчают жизнь для крупных проектов. Честно говоря, я считаю, что фреймворки доставляют больше хлопот, чем они стоят для небольших проектов. Я бы посоветовал OP не путать Dependency Injection со структурами, которые его поддерживают.
RubberDuck
1
хорошо сказано. И зачем изобретать велосипед, если кто-то уже сделал тот, который уже хорош и крут?
jwenting
Именно это. За исключением того, что мне не нужно изменять какой-либо код реализации - конечно, кода создания нет ;-)
Матье Гиндон
Похоже, что ваши библиотеки DI отстой. Хорошие могут угадать класс для создания экземпляра с помощью отражения.
Флориан Маргэйн
2
любой, кто использует отражение для обработки во время выполнения, делает это неправильно. Отражение - это одна из тех технологий, которая только потому, что вы можете что-то делать, не означает, что вы должны это делать.
gbjbaanb
12
  1. Зачем нам вообще нужен DI (Dependency Injection)?

    Механизм DI отделяет производство объекта от потребления объекта. Зависимости, в которых нуждается объект, доставляются прозрачным извне. Преимущество этого механизма очевидно: вы можете в любое время обмениваться зависимостями, например, используя нулевой объект для тестирования.

  2. Как это сделать?

    Есть несколько способов достижения цели:

    • Внедрение зависимостей через конструктор
    • Впрыск через геттер / сеттер
    • Интерфейс впрыска
  3. Нужны ли нам DI-фреймворки?

    Нет, совсем нет. Вы можете просто передать все экземпляры другим объектам вручную. Если у вас небольшое приложение, вам не понадобится пружинный контейнер.

    Но с другой стороны, фреймворки помогают вам в управлении объектами:

    • Они помогают вам установить сложные объектные отношения. Вы не должны писать шаблонный код, генерировать экземпляры и передавать их соответствующим объектам.

    • Они помогают вам контролировать, когда создается объект: вы можете создавать экземпляры во время начальной загрузки приложения, но в некоторых случаях ленивое создание - только при необходимости - лучше

    • Они помогают вам контролировать, сколько экземпляров создается: по одному на время жизни приложения или по одному на запрос (если вы занимаетесь веб-программированием)

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

Томас Джанк
источник
2
Вы можете использовать библиотеки DI вообще без фреймворка.
Флориан Маргэйн
5

С весной это в основном вопрос удобства.

Если у вас есть класс, TopLevelкоторый конструирует класс, MiddleLevelкоторый конструирует класс LowLevel, и вы понимаете, что вам нужен новый параметр конструктора LowLevel, вы должны также добавить его TopLevelи MiddleLevelпросто, чтобы, когда пришло время для MiddleLevelсоздания LowLevelзначения, было доступно так что это может быть передано его конструктору. С весной вы просто добавляете аннотацию.

Кроме того, с помощью Spring можно определять зависимости во внешнем файле конфигурации вместо xml, и это, предположительно, дает вам возможность генерировать новую систему с совершенно другой разводкой «без изменения какого-либо кода». (ИМХО, это полностью неверно направлено, потому что изменение xml не так сильно отличается от изменения кода, и на самом деле код обычно имеет гораздо лучшую проверку ошибок и проверку типов, чем xml.)

Другое дело, что многие люди боятся конструкторов; они не понимают их, они не любят их, они предпочли бы не использовать их.

Майк Накис
источник
3
В основном согласен, особенно с XML-замечанием. ИМХО, бояться конструкторов, вероятно, плохая причина для использования DI-фреймворка.
Роберт Харви
2
ИМХО, боязнь конструкторов - это хороший повод держаться подальше от программирования. C -: =
Майк Накис
5
Но как это преимущество перед фабрикой (статическое или иное)? (Который имеет преимущество в качестве опции, которую вы можете использовать в зависимости от обстоятельств, в то время как весна, кажется, - «все или ничего»)
Ричард Тингл
@RichardTingle Spring может представлять преимущество, главным образом, из-за всех других вещей, которые он делает, кроме DI, потому что, очевидно, вы можете достичь DI многими другими способами, статическими фабриками, являющимися одним. (Один из наименее крутых, но все же.) Но возникает вопрос, нужно ли использовать пружину для достижения DI, и вот на что я пытался ответить: в принципе, это не обязательно, просто удобство. ,
Майк Накис
Это пример того, чем DI не является. «TopLevel» не должен создавать MiddleLevel, но должен получать его при конструировании TopLevelв качестве аргумента для конструктора. Аналогично MiddleLevelдолжен получить LowLevelв своем конструкторе.
уточнение
1

Несколько лет назад я написал программу для мониторинга веб-страниц, веб-портлетов, даже определенных таблиц базы данных, в компании, в которой я работал. Я хотел, чтобы он был достаточно гибким, чтобы пользователь мог указать, какие мониторы будут работать и с какими параметрами (URL-адреса, имена входа, критерии успеха и т. Д.). Поэтому я написал его для чтения из файла XML и использования отражения Java для создания экземпляров указанных классов и использования методов установки для установки указанных параметров.

Позже я узнал, что Spring сделает то же самое для вас, и многое другое.

Так что в моем случае я обнаружил, что

  1. Использование структуры внедрения зависимостей помогает сделать программу гибкой и упростить определение того, как она будет работать (в рамках четко определенных параметров, конечно).

  2. Использование стороннего DI-фреймворка избавляет вас от необходимости изобретать велосипед.

Пол Дж Абернати
источник
4
Не могли бы вы подробнее объяснить, почему определение того, какой конкретный класс использовать, лучше в XML-файле, а не в Java-файле. Этого я никогда не понимал.
Ричард Тингл
1
Это не волшебная палочка, но одно преимущество использования конфигурационных файлов состоит в том, что, по крайней мере, теоретически, их легче редактировать, чем код. Кроме того, они могут быть изменены пользователем, который запускает вашу программу, но не имеет доступа к вашему исходному коду. В примере, который я привел в своей грубой программе внедрения зависимостей, я иногда изменял XML-файл конфигурации, чтобы я мог изменить способ запуска программы, даже если я был тем, кто ее написал. Если вам не нужна внешняя конфигурируемость, это может быть проще сделать с помощью кода. У меня была другая работа, где мы делали весь DI в коде, и это работало хорошо.
Пол Дж. Абернати