Различие между созданием нового объектного и внедрения зависимости

Каково различие между созданием нового объектного и внедрения зависимости? Объясните подробно.

22
задан Alberto Zaccagni 2 August 2010 в 10:33
поделиться

5 ответов

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

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

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

16
ответ дан 29 November 2019 в 03:47
поделиться

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

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

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

16
ответ дан 29 November 2019 в 03:47
поделиться

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

3
ответ дан 29 November 2019 в 03:47
поделиться

При использовании контейнера инверсии управления для выполнения внедрения зависимостей контейнер создает объекты, а не разработчик. Это сделано для того, чтобы контейнер мог «внедрить» эти объекты в другие объекты.

2
ответ дан 29 November 2019 в 03:47
поделиться

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

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

Предположим, что класс Holder требует объект класса Handle. Традиционный способ сделать это - позволить экземпляру Holder создавать и владеть им:

class Holder {
    private Handle myHandle = new Handle();
    public void handleIt() {
        handle.handleIt();
    }
}

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

Путем внедрения экземпляра Handle, например, в конструктор, кто-то извне становится ответственным за создание экземпляра.

class Holder {
    private Handle myHandle;

    public Holder(Handle injectedHandle) {
        myHandle = injectedHandle;
    }

    public void handleIt() {
        handle.handleIt();
    }
}

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

Фактическая инъекция будет происходить в каком-то другом месте, обычно в какой-то «основной» программе.Есть несколько фреймворков, которые могут помочь вам сделать это без программирования, но, по сути, это код в «основной» программе:

...
private Handle myHandle = new Handle(); // Create the instance to inject
private Handler theHandler = new Handler(myHandle); // Inject the handle
...

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

25
ответ дан 29 November 2019 в 03:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: