Как объяснить введение зависимости 5-летнему ребенку? [закрыто]


208

Что такое хороший способ объяснить внедрение зависимости ?

Я нашел несколько учебных пособий в Google, но ни один из них не предполагал, что читатель - просто новичок в Java. Как бы вы объяснили это новичку?


72
Похоже, у этого ребенка тяжелая жизнь ...
ire_and_curses

24
Начните с "Однажды ....."
Мартин,

1
Мы говорим о Java-новичке или буквально пятилетнем?
Дрю

2
# Инъекция зависимости # не зависит от возраста ученика, он одинаков для всех
Ракеш Джуал

2
Ракеш: вводное видео о JavaOne 2009 построено на предпосылке, что даже 13-летний специалист может быть разработчиком Java, потому что Java «везде» и «проста».
Esko

Ответы:


789

Я даю вам инъекцию зависимости для пятилетних детей.

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

То, что вы должны делать, это заявить о необходимости: «Мне нужно что-нибудь выпить с обедом», и тогда мы позаботимся о том, чтобы у вас было что-нибудь, когда вы сядете поесть.


93

Как насчет этого?

Если у вас есть класс , Employeeи этот сотрудник имеет Address вы можете иметь Employeeкласс , определяемый следующим образом :

class Employee {
    private Address address;

    // constructor 
    public Employee( Address newAddress ) {
        this.address = newAddress;
    }

    public Address getAddress() {
    return this.address;
    }
    public void setAddress( Address newAddress ) {
        this.address = newAddress;
    }
}

Пока все выглядит хорошо.

Этот код показывает отношения HAS-A между сотрудником и его адресом, это нормально.

Теперь это HAS-A создали зависимость между ними. Проблема заключается в конструкторе.

Каждый раз, когда вы хотите создать Employeeэкземпляр, вам нужен Addressэкземпляр:

 Address someAddress = ....
 Employee oscar = new Employee( someAddress ); 

Работать таким образом становится проблематично, особенно если вы хотите выполнить модульное тестирование.

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

Чтобы избежать этого, вы можете изменить конструктор следующим образом:

  public Employee(){
  }

Использование конструктора без аргументов.

Тогда вы можете установить адрес когда захотите:

 Address someAddress = ....
 Employee oscar = new Employee();
 oscar.setAddress( someAddress ); 

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

Тем не менее, подумайте об этом, скажем, вы добавляете Departmentатрибут:

  class Employee {
      private Address address;
      private Department department;

  ....

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

Что Injection Dependency все об этом , чтобы помочь вам, ну, «Inject» эта зависимость в вашем коде. Большинство платформ позволяют вам сделать это, указав во внешнем файле, какой объект должен быть введен.

Предположим, файл свойств для фиктивного инжектора зависимостей:

  #mock employee
  employee.address = MockAddress.class
  employee.department = MockDepartment.class

  #production setup 
  employee.address = RealAddress.class
  employee.department = RealDepartment.class

Вы определите, что вводить для данного сценария.

Платформа Dependency Injector будет делать для вас правильные объекты, чтобы вам не приходилось кодировать setAddressили setDepartment. Это может быть сделано либо путем отражения, либо путем генерации кода или других методов.

Таким образом, в следующий раз, когда вам нужно будет протестировать Employeeкласс, вы можете внедрить макет Addressи Departmentsобъекты, не кодируя весь набор / получение для всего вашего теста. Более того, вы можете внедрять реальные Address и Departmentобъекты в производственный код, и при этом сохранять уверенность, что ваш код работает так, как было протестировано.

Это довольно много об этом.

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

Я надеюсь, что вы все еще находите это полезным.


3
Или: инъекции зависимостей - это когда вы что- то устанавливаете для себя. Это что-то, как правило, рамки. :)
OscarRyz

2
действительно очень умный.
OscarRyz

24

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

Более мощный метод заключается в том, чтобы иметь возможность создавать ваш объект и предоставлять ему зависимости для использования. Таким образом, вы можете создать соединение с базой данных и затем передать его вашему объекту. Таким образом, вы можете создавать свой объект с разными зависимостями в разное время, делая ваш объект более гибким. Это внедрение зависимостей, где вы «внедряете» зависимости в объект.

Кстати: в современном стиле презентации с использованием фотографий flickr для иллюстрации концепций это можно проиллюстрировать, когда наркоман заигрывает с наркотиками. Ой, подождите, это зависимость от инъекций ... Хорошо, извините, плохая шутка.


10

Я не знаю ни одного упрощенного учебника, но могу дать вам почти 25 250 слов или меньше:

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

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


7

Когда вы получаете новый Nintendo, вы можете просто использовать кнопки и сенсорный экран, чтобы играть в игры.

Но на фабрике Nintendo им нужно знать, как их собрать.

Когда умные люди на фабрике выпускают Nintendo DS, все будет по-другому, но вы все равно будете знать, как им пользоваться.


5
Это больше похоже на описание интерфейсов или полиморфизма, но я отдаю вам должное за то, что вы на самом деле понятны для пятилетнего ребенка.
Натикс
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.