Разница между созданием нового объекта и инъекцией зависимостей
В чем разница между созданием нового объекта и инъекцией зависимостей? Пожалуйста, объясните подробно.
Ответы
Ответ 1
Ну,
создание нового объекта настолько явственно, насколько это возможно - вы создаете новый экземпляр желаемого класса.
Инъекции зависимостей - это механизм, который предоставляет вам ссылки, где они вам нужны.
Представьте себе класс, представляющий пул соединений в вашей базе данных - обычно у вас есть только один экземпляр этого класса. Теперь вам нужно распространить эту ссылку на все классы, которые ее используют.
Здесь вам может понадобиться Dependency Injection - с помощью среды DI, такой как Spring, вы можете определить, что один экземпляр вашего пула будет введен в классы, которые в нем нуждаются.
Ваш вопрос сам по себе нелегко ответить, так как создание объекта и инъекции зависимостей не могут быть легко сравнимы...
Ответ 2
Ну, они не совсем сопоставимы. Вам всегда придется создавать новый объект, создавая экземпляр класса в какой-то момент. Внедрение зависимостей также требует создания новых объектов.
Внедрение зависимостей действительно вступает в игру, когда вы хотите контролировать или проверять поведение экземпляров, используемых классом, который вы используете или хотите проверить. (Для Test Driven Development внедрение зависимостей является ключевым для всех, кроме самого маленького примера).
Предположим, что класс 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 вместо реального экземпляра может быть введен фиктивный или тупиковый объект, позволяющий проверить или контролировать взаимодействие между Holder, его вызывающей стороной и дескриптором.
Фактическая инъекция будет происходить в каком-то другом месте, обычно в какой-то "основной" программе. Есть несколько фреймворков, которые могут помочь вам сделать это без программирования, но по сути это код в "основной" программе:
...
private Handle myHandle = new Handle(); // Create the instance to inject
private Handler theHandler = new Handler(myHandle); // Inject the handle
...
По сути, инъекция - это не более чем необычный метод set
. И, конечно, вы можете реализовать механизм внедрения, используя его вместо конструктора, как в простом примере выше.
Ответ 3
Конечно, оба создают объекты. Разница в том, кто несет ответственность за создание. Является ли он классом, который нуждается в его зависимостях или контейнере, например, Spring, который связывает компоненты с зависимостями. Вы настраиваете зависимости в отдельном файле конфигурации (обычно XML).
Это действительно разделение проблем. Класс говорит, что мне нужно это, этот и этот компонент, чтобы я работал правильно. Класс не заботится о том, как он получает свои компоненты. Вы вставляете их в класс с отдельным конфигурационным файлом.
Чтобы дать вам пример, рассмотрим наличие класса покупок, которому необходим модуль оплаты. Вы не хотите жестко указывать, какой платежный модуль будет использоваться. Для этого вы можете инвертировать элемент управления. Вы можете изменить используемый платежный модуль несколькими нажатиями клавиш в файле конфигурации контейнера. Сила в том, что вы не трогаете какой-либо Java-код.
Ответ 4
Инъекции в зависимости от приложения добавляют в ваше приложение уровень настраиваемости. В том смысле, когда вы создаете жесткую конструкцию кода, вам нужно повторно собрать и повторно развернуть приложение, но когда вы используете инъекцию зависимостей, вы можете настроить XML и изменить поведение без повторной установки и повторного развертывания. Существует множество вариантов использования, где это может сэкономить много усилий и усилий.
Ответ 5
При использовании контейнера с инверсией контроля для выполнения инъекции зависимостей контейнер создает объекты, а не разработчик. Это делается для того, чтобы контейнер мог "вставлять" эти объекты в другие объекты.
Я бы посоветовал вам прочитать некоторые статьи об инъекции зависимостей и/или spring. Или прочитайте другие темы об инъекции зависимостей здесь на SO.