Чем внедрение зависимостей отличается от просто не использования глобальных переменных? - PullRequest
16 голосов
/ 26 марта 2011

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

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

Ответы [ 6 ]

21 голосов
/ 30 марта 2011

Внедрение зависимостей связано с разъединением кода.

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

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

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 в случаях, описанных выше.Чем больше вашего кода отсоединено, тем меньше изменений кода вам нужно будет сделать.

5 голосов
/ 26 марта 2011

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

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

2 голосов
/ 04 апреля 2011

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

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

 <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 и т. Д.) - это действительно приятно.Все это вместе делает структуры внедрения зависимостей весьма привлекательными для использования по сравнению с выполнением всего этого самостоятельно.

1 голос
/ 04 апреля 2011

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

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

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

1 голос
/ 26 марта 2011

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

0 голосов
/ 04 апреля 2017

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

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

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

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

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

...