Який хороший спосіб пояснити ін'єкцію залежності ?
У Google я знайшов кілька навчальних посібників, але жоден із них, який би припустив читача, не є початківцем Java. Як би ви пояснили це новачку?
Який хороший спосіб пояснити ін'єкцію залежності ?
У Google я знайшов кілька навчальних посібників, але жоден із них, який би припустив читача, не є початківцем Java. Як би ви пояснили це новачку?
Відповіді:
Я даю вам ін'єкцію залежності для п’ятирічних дітей.
Коли ви підете і дістанете речі з холодильника для себе, ви можете викликати проблеми. Ви можете залишити двері відкритими, ви можете отримати щось, чого мама чи тато не хочуть. Ви навіть можете шукати те, чого ми навіть не маємо або термін дії якого закінчився.
Що ви повинні робити, це заявити про необхідність: "Мені потрібно щось випити за обідом", і тоді ми переконаємося, що у вас є щось, коли ви сідете їсти.
Як що до цього?
Якщо у вас є клас, 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(){
}
Використання конструктора no args.
Тоді ви можете встановити адресу коли завгодно:
Address someAddress = ....
Employee oscar = new Employee();
oscar.setAddress( someAddress );
Тепер це може бути перетягуванням, якщо у вас є кілька атрибутів або якщо об'єкти важко створити.
Але подумайте над цим, скажімо, ви додасте Department
атрибут:
class Employee {
private Address address;
private Department department;
....
Якщо у вас є 300 співробітників, і всі вони повинні мати один і той же відділ, і плюс той самий відділ має бути розподілений між деякими іншими об'єктами (наприклад, списком департаментів компанії або ролями, які має кожен відділ тощо), тоді ви будете мати нелегко Department
бачити видимість об’єкта та ділитися ним через усю мережу об’єктів.
У чому полягає інжекція залежностей, щоб допомогти вам «ввести» ці залежності у свій код. Більшість фреймворків дозволяють це зробити, вказавши у зовнішньому файлі, який об’єкт потрібно вводити.
Припустимо файл властивостей для фіктивного інжектора залежностей:
#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-річного віку, як ви просили.
Я сподіваюся, що ви все ще вважаєте його корисним.
Коли ви пишете клас, природно використовувати інші об’єкти. Можливо, наприклад, підключення до бази даних або інша послуга, яку ви використовуєте. Ці інші об'єкти (або послуги) - це залежності. Найпростіший спосіб написання коду - це просто створити та використовувати ці інші об'єкти. Але це означає, що ваш об’єкт має негнучкі стосунки до цих залежностей: незалежно від того, чому ви посилаєтесь на свій об'єкт, він використовує ті самі залежності.
Більш потужна техніка - вміти створювати свій об’єкт і забезпечувати його залежностями для використання. Таким чином, ви можете створити з'єднання з базою даних для використання, а потім передати його своєму об'єкту. Таким чином, ви можете створювати свій об'єкт з різними залежностями в різний час, роблячи ваш об'єкт більш гнучким. Це введення залежності, коли ви "вводить" залежності в об'єкт.
BTW: У сучасному стилі викладу використання фотографій Flickr для ілюстрації концепцій це можна проілюструвати наркоманом, який розстрілює наркотики. О, чекайте, це залежність від ін'єкцій ... Добре, вибачте, поганий жарт.
Я не знаю жодних спрощених навчальних посібників, але я можу дати вам майже 25 версій на 250 слів або менше:
При введенні залежності об'єкт не конфігурує власні компоненти на основі речей, які він уже знає, скоріше об'єкт налаштовується логікою вищого рівня, а потім викликає компоненти, для яких у нього не було вбудованого передбачення. Ідея полягає в тому, щоб зробити об'єкт більше компонентом і менше додатком, перемістивши завдання конфігурації на більш високий рівень. Це робить об'єкт більш імовірним у майбутньому або з іншою конфігурацією.
Краще для тестування, краще, коли настане час переглянути додаток. Типова реалізація ставить конфігурацію в XML і використовує рамки для динамічного завантаження класів.
Коли вам нададуть новий Nintendo, ви можете просто використовувати кнопки та сенсорний екран, щоб грати в ігри.
Але на фабриці Nintendo вони повинні знати, як скласти її.
Коли розумні люди на заводі виведуть Nintendo DS, всередині буде інакше, але ви все одно будете знати, як ним користуватися.