Как инъекция зависимостей отличается от того, что она не использует глобальные переменные?

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

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

Ответ 1

Включение зависимостей относится к развязывающему коду.

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

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

def foo(arg):
   return ClassBar(arg).attr

foo(1)

Функция foo зависит от или тесно связана с ClassBar. Причина в том, что это не хорошо, вам придется обновлять foo, когда:

  • аргументы построения ClassBar изменить
  • вы хотите изменить ClassBar на что-то еще
  • другая часть кода хочет получить доступ к attr из другого объекта

Если код был переписан:

def foo(instanceBar):
   return instanceBar.attr

foo(ClassBar(1))

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

Ответ 2

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

Итак, значение здесь - разделение проблем. Это полезно для тестирования, когда вы будете вводить макет реального объекта.

Ответ 3

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

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

 <bean id="world" class="com.game.World" start-method="play">
    <property name="player1" ref="player1"/>
    <property name="player2" ref="player2"/>
 </bean>

 <bean id="player1" class="com.game.LocalPlayer"/>
 <bean id="player2" class="com.game.NetworkPlayer/>

Это было бы не иначе, как если бы вы создали объекты вручную:

 public static void main() {
    World world = new World();
    world.player1 = new LocalPlayer();
    world.player2 = new NetworkPlayer();

    world.play();
 }

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

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

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

Ответ 4

Другое дело, что инъекция зависимости обычно создает одноэлементные объекты. В таких ситуациях, как службы и DAO, вы никогда не захотите иметь более одного объекта. Его также приятно, если он уже создан (обычно при запуске приложения, в spring), поэтому вы можете использовать каждый раз, когда возникнет необходимость.

Ответ 5

Предполагая, что вы хороший кодер, вы хотите легко протестировать и заменить систему запасных частей. Лучший способ сделать это - это модульный дизайн. То есть вы хотите разбить свою проблему на более мелкие проблемы, которые вы можете решить, и не допускайте ошибок.

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

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

Ответ 6

Использование инъекции зависимостей похоже на использование реестра Windows. Вы загружаете реестр теми вещами, которые хотите, а затем вытаскиваете их и используете в каком-либо модуле.

Однако он разбивает объектно-ориентированный код.

Скажем, у вас есть 20 элементов в вашем реестре Dependency. База данных, регистратор, обработчик исключений и т.д.

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

Я не вижу никакой пользы здесь. Это просто делает отладку невозможной.