Уже было опубликовано несколько вопросов со специальными вопросами о внедрении зависимости , например, когда его использовать и какие существуют рамки для него. Тем не менее,
Что такое внедрение зависимостей и когда / почему его следует или не следует использовать?
Внедрение зависимости передает зависимость другому объекты или платформа (инжектор зависимости).
Внедрение зависимости делает тестирование легче. Инжекция может быть сделана до [1 124] конструктор .
SomeClass()
имеет его конструктора как следующее:
public SomeClass() {
myObject = Factory.getObject();
}
проблема : Если myObject
включает сложные задачи, такие как доступ к диску или доступ к сети, это твердо , чтобы сделать модульный тест на SomeClass()
. Программисты должны дразнить myObject
, и мог бы прерывание вызов фабрики.
Альтернативное решение :
myObject
в как аргумент конструктору public SomeClass (MyClass myObject) {
this.myObject = myObject;
}
myObject
может быть передана непосредственно, который делает тестирование легче.
более трудно изолировать компоненты в поблочном тестировании без внедрения зависимости.
В 2013, когда я записал этот ответ, это было главной темой на Google Testing Blog . Это остается самым большим преимуществом для меня, поскольку программистам не всегда нужна дополнительная гибкость при их разработке во время выполнения (например, для сервисного локатора или подобных шаблонов). Программисты часто должны изолировать классы во время тестирования.
Лучшее определение, которое я нашел до сих пор, один James Shore :
"Внедрение зависимости" является термином за 25 долларов для понятия за 5 центов. [...] Внедрение зависимости означает давать объекту свои переменные экземпляра. [...].
существует статья Martin Fowler , который может оказаться полезным, также.
Внедрение зависимости в основном обеспечивает объекты, в которых объект нуждается (его зависимости) вместо того, чтобы иметь его создают их сам. Это - очень полезная техника для тестирования, так как это позволяет зависимостям дразниться или гаситься.
Зависимости могут быть введены в объекты многими средствами (такими как инжекция конструктора или инжекция метода set). Можно даже использовать специализированные платформы внедрения зависимости (например, Spring), чтобы сделать это, но они, конечно, не требуются. Вам не нужны те платформы, чтобы иметь внедрение зависимости. Инстанцирование и передача объектов (зависимости) явно являются столь же хорошей инжекцией как инжекция платформой.
Внедрение зависимости является практикой, где объекты разработаны способом, где они получают экземпляры объектов от других частей кода, вместо того, чтобы создать их внутренне. Это означает, что в любом объекте, реализовывая интерфейс, который требуется объектом, можно заменить, не изменяя код, который упрощает тестирование и улучшает отделение.
, Например, рассмотрите эти классы:
public class PersonService {
public void addManager( Person employee, Person newManager ) { ... }
public void removeManager( Person employee, Person oldManager ) { ... }
public Group getGroupByManager( Person manager ) { ... }
}
public class GroupMembershipService() {
public void addPersonToGroup( Person person, Group group ) { ... }
public void removePersonFromGroup( Person person, Group group ) { ... }
}
В этом примере, для реализации PersonService::addManager
и PersonService::removeManager
был бы нужен экземпляр GroupMembershipService
, чтобы сделать его работу. Без Внедрения зависимости традиционный способ сделать это состоял бы в том, чтобы инстанцировать нового GroupMembershipService
в конструкторе PersonService
лет и использовать тот атрибут экземпляра в обеих функциях. Однако, если у конструктора GroupMembershipService
лет есть несколько вещей, это требует, или хуже все же, существует некоторая инициализация "методы set", которые нужно назвать на эти GroupMembershipService
, код растет скорее быстро, и PersonService
теперь зависит не только от GroupMembershipService
, но также и все остальное, что GroupMembershipService
зависит от. Кроме того, связь с [1 111] является hardcoded в PersonService
, что означает, что Вы не можете "макет" GroupMembershipService
для тестирования, или использовать стратегическую модель в различных частях Вашего приложения.
С Внедрением зависимости, вместо того, чтобы инстанцировать GroupMembershipService
в Вашем PersonService
, Вы или передали бы его в PersonService
конструктор или иначе добавили бы Свойство (метод считывания и метод set) для установки локального экземпляра его. Это означает, что Ваш PersonService
больше не должен волноваться о том, как создать GroupMembershipService
, это просто принимает тех, это дано и работает с ними. Это также означает, что что-либо, что является подклассом [1 119], или реализует эти GroupMembershipService
, интерфейс может быть "введен" в эти PersonService
, и эти PersonService
не должен знать об изменении.