Що таке введення залежності та інверсія управління у весняних рамках?


111

"Введення залежностей" та "Інверсія управління" часто згадуються як основні переваги використання Весняної рамки для розробки веб-рамок

Чи може хтось пояснити, що це таке, дуже просто, прикладом, якщо це можливо?



3
@SteveChambers - це не дублікат, це питання задається у "Спрингс-перспектива". Це питання загалом є перспективним.
VdeX

Відповіді:


233
  • Весна допомагає у створенні вільно поєднаних додатків через Dependency Injection .
  • Навесні об'єкти визначають свої асоціації (залежності) і не переживають, як вони отримають ці залежності . Весна несе обов'язки забезпечити необхідні залежності для створення об'єктів.

Наприклад : Припустимо, у нас є об'єкт, Employeeі він має залежність від об'єкта Address. Ми визначимо, що відповідає бобу Employee, визначимо його залежність від об'єкта Address.

Коли Spring спробує створити Employeeоб'єкт, він побачить, що Employeeмає залежність від Address, тому спочатку створить Addressоб'єкт (залежний об'єкт), а потім введе його в Employeeоб'єкт.

  • Інверсія управління ( IoC ) та вприскування залежності ( DI ) використовуються взаємозамінно. IoC досягається завдяки DI. DI - це процес забезпечення залежностей, а IoC - кінцевий результат DI. ( Примітка: DI - не єдиний спосіб досягти IoC. Є й інші способи .)

  • За DI, відповідальність за створення об'єктів перекладається з нашого коду програми на контейнер Spring; це явище називається IoC.

  • Впорскування в залежності може бути виконано за допомогою інжектора сетеру або введення конструктора.

Я не погоджуюсь. я не думаю, що це чітке пояснення. Чому ви не можете просто створити "Адреса" всередині "Співробітника", а не отримати рамку для її створення та введення? Закликається дещо детальніший приклад.
Борис

2
@Boris Ніхто не сказав, що ти не можеш створити власні об'єкти. Але єдиною метою відповіді було продемонструвати, як можна досягти того ж за допомогою DI. Ви можете мати як DI, так і об'єкти, ініційовані кодом клієнта. Це все ще називали б МОК, принаймні частково.
bogdan.rusu


Борис. Ревно багато? Це найкраща відповідь коли-небудь.
Анікет Капсе

31

Я запишу своє просте розуміння цих двох термінів: (Для швидкого розуміння просто читайте приклади)

  • Ін'єкція залежностей (DI):
    Введення залежності, як правило, означає передачу залежного об'єкта в якості параметра методу, а не примушення методу створювати залежний об'єкт .
    На практиці це означає, що метод не має прямої залежності від конкретної реалізації; будь-яка реалізація, яка відповідає вимогам, може передаватися як параметр.

    При цьому реалізація об'єктів визначає їх залежності. А весна робить її доступною.
    Це призводить до слабко пов'язаної розробки додатків.

    Короткий приклад: ОБ'ЄКТ ПРАЦІВНИКА, КОГО СТВОРЕНО, АВТОМАТИЧНО СТВОРИТЬ ОБ'ЄКТ АДРЕСИ (якщо адреса визначається як залежність від об'єкта працівника) *.

  • Контейнер інверсії управління (IoC):
    Це загальна характеристика фреймворків, IoC управляє об'єктами java
    - від інстанції до знищення через його BeanFactory.
    - компоненти Java, які інстанціюються контейнером IoC, називаються квасолею, а контейнер IoC керує сферою дії квасолі, подіями життєвого циклу та будь-якими функціями AOP, для яких він був налаштований та кодований.

    QUICK EXAMPLE:Inversion of Control is about getting freedom, more flexibility, and less dependency. When you are using a desktop computer, you are slaved (or say, controlled). You have to sit before a screen and look at it. Using keyboard to type and using mouse to navigate. And a bad written software can slave you even more. If you replaced your desktop with a laptop, then you somewhat inverted control. You can easily take it and move around. So now you can control where you are with your computer, instead of computer controlling it.

    Реалізуючи Inversion of Control, споживач програмного забезпечення / об’єктів отримує більше елементів управління / опцій над програмним забезпеченням / об'єктами, замість того, щоб контролюватись або мати менше можливостей.

    Інверсія управління як настанова на проектування служить таким цілям:
    - Існує роз'єднання виконання певного завдання від реалізації.
    - Кожен модуль може зосередитись на тому, для чого він призначений.
    - Модулі не припускають, що роблять інші системи, але розраховують на їх контракти.
    - Заміна модулів не побічно впливає на інші модулі

Я буду тримати абстрактні речі тут, ви можете відвідати наступні посилання для детального розуміння теми.

Гарне прочитання з прикладом

Детальне пояснення


11

Навесні Об'єкти вільно з'єднані, тобто кожен клас незалежний один від одного, так що все можна перевірити індивідуально. Але при використанні цих класів клас може залежати від інших класів, які потрібно спочатку інстанціювати.

Отже, ми весною повідомляємо, що клас A залежить від класу B. Отже, створюючи квасоля (як клас) для класу A, вона створює клас B до класу A і вводить його в клас A, використовуючи сеттер або конструктор DI методами. Тобто, ми весною говоримо про залежність під час виконання. Це DI.

Оскільки ми покладаємо на себе відповідальність за створення об'єктів (бобів), збереження їх та їх агрегацій до Spring, а не жорсткого кодування, ми називаємо це Inversion Of Control (IOC).


7

Інверсія управління (МОК):

IoC - це схема дизайну, яка описує інвертування потоку управління в системі, тому потік виконання не контролюється центральним фрагментом коду. Це означає, що компоненти повинні залежати лише від абстракцій інших компонентів і не нести відповідальності за обробку створення залежних об'єктів. Натомість екземпляри об'єктів подаються під час виконання контейнером IoC через введення залежностей (DI).

IoC дозволяє покращити дизайн програмного забезпечення, що сприяє повторному використанню, слабкому з'єднанню та легкому тестуванню компонентів програмного забезпечення.

Впорскування в залежності (DI):

DI - це техніка передачі залежностей конструктору об'єкта. Якщо об'єкт був завантажений з контейнера, його залежність буде автоматично поставлена ​​контейнером. Це дозволяє споживати залежність без необхідності вручну створювати екземпляр. Це зменшує з'єднання і дає вам більший контроль за терміном експлуатації об'єктів.

натисніть, щоб переглянути більше


6

Весна: Весна є контейнером "Інверсія управління" для платформи Java.

Інверсія управління (IoC): Інверсія управління (IoC) - це об'єктно-орієнтована програма програмування, за якою об'єктна зв'язок обмежується під час виконання об'єктом "асемблера" і, як правило, не відома під час компіляції за допомогою статичного аналізу.

Ін'єкція залежностей (DI): "Введення залежностей - це модель дизайну програмного забезпечення, яка дозволяє усунути твердо кодовані залежності та дає змогу змінити їх, як під час виконання, так і під час компіляції." -вікі.


Чим це простіше, ніж те, що вже є там (звідки виходить ця відповідь)? Він не враховує запит ОП про спрощення, якщо тільки подвійні цитати навколо термінологій не вкрай спрощують ситуацію.
Полум’я удуна

6

Інверсія управління. Це означає передавати контроль над створенням та інстанцією весняних бобів до контейнера Spring IOC, і єдиною роботою, яку розробник виконує, є налаштування бобів у весняному файлі xml.

Ін'єкційна залежність-

Розглянемо клас працівника

class Employee { 
   private int id;
   private String name;
   private Address address;

   Employee() {
     id = 10;
     name="name";
     address = new Address();
   }


}

і розглянути адресу класу

class Address {
   private String street;
   private String city;

   Address() {
     street="test";
     city="test1";

  }
}

У наведеному вище коді значення адресного класу будуть встановлені лише тоді, коли клас Employee є екземпляром, що є залежністю класу Address від класу Employee. І весна вирішує цю проблему, використовуючи концепцію введення залежності, надаючи два способи введення цієї залежності.

  1. Ін'єкція сетера

Метод встановлення в класі Співробітник, який бере посилання на клас адреси

public void setAddress(Address addr) {
    this.address = addr;
}
  1. Інжекція конструктора

Конструктор у класі Співробітник, який приймає адресу

Employee(Address addr) {
      this.address = addr;
}

Таким чином, значення класу Адреси можна встановити незалежно, використовуючи або інжектор сектора / конструктора.


3

Інверсія управління - це загальний принцип дизайну архітектури програмного забезпечення, який допомагає створювати багаторазові модульні рамки програмного забезпечення, які прості в обслуговуванні.

Це принцип дизайну, в якому Потік управління "отримується" з загальнонаписаної бібліотеки або коду для багаторазового використання.

Щоб краще зрозуміти, давайте подивимось, як ми звикли кодувати в попередні дні кодування. У процедурній / традиційній мовах бізнес-логіка, як правило, контролює потік програми та "викликає" загальний або багаторазовий код / ​​функції. Наприклад, у простому додатку консолі мій потік управління контролюється вказівками моєї програми, які можуть включати виклики до деяких загальних функцій багаторазового використання.

print ("Please enter your name:");
scan (&name);
print ("Please enter your DOB:");
scan (&dob);

//More print and scan statements
<Do Something Interesting>

//Call a Library function to find the age (common code)
print Age

На відміну від IoC, Frameworks - це багаторазовий код, який "викликає" ділову логіку.

Наприклад, у системі на базі Windows вже буде доступна рамка для створення елементів інтерфейсу, таких як кнопки, меню, вікна та діалогові вікна. Коли я пишу бізнес-логіку моєї заявки, події фреймворку називатимуть моїм кодом ділової логіки (коли подія запускається), а НЕ навпаки.

Хоча код рамки не знає моєї логіки бізнесу, він все одно буде знати, як викликати мій код. Це досягається за допомогою подій / делегатів, зворотних дзвінків тощо. Тут управління потоком "перевернуте".

Отже, замість залежності потоку управління на статично пов'язаних об'єктах потік залежить від загального графіка об'єкта та відносин між різними об'єктами.

Dependency Injection - це схема проектування, яка реалізує принцип IoC для вирішення залежностей об'єктів.

Простіше кажучи, коли ви намагаєтеся написати код, ви будете створювати та використовувати різні класи. Один клас (клас A) може використовувати інші класи (клас B та / або D). Отже, клас B і D - залежності класу А.

Простий аналогією буде автомобіль класу. Автомобіль може залежати від інших класів, таких як Двигун, Шини тощо.

Ін'єкція залежності залежить від того, щоб замість залежних класів (тут класу автомобілів) створювати свої залежності (Class Engine і Class Tire), класу слід вводити конкретний екземпляр залежності.

Давайте розберемося з більш практичним прикладом. Подумайте, що ви пишете власний TextEditor. Крім усього іншого, ви можете мати перевірку орфографії, яка надає користувачеві можливість перевіряти друкарські помилки в його тексті. Проста реалізація такого коду може бути:

Class TextEditor
{

    //Lot of rocket science to create the Editor goes here

    EnglishSpellChecker objSpellCheck;
    String text;

    public void TextEditor()

    {   

        objSpellCheck = new EnglishSpellChecker();

    }

    public ArrayList <typos> CheckSpellings()
    {

        //return Typos;

    }

}

На перший погляд, все виглядає рум’яно. Користувач напише текст. Розробник захопить текст і зателефонує у функцію CheckSpellings і знайде список помилок, які він покаже користувачеві.

Здається, все працює чудово до одного прекрасного дня, коли один користувач почне писати французькою мовою в редакторі.

Щоб забезпечити підтримку більшої кількості мов, нам потрібно мати більше SpellCheckers. Можливо, французька, німецька, іспанська тощо.

Тут ми створили щільно поєднаний код, причому "англійський" SpellChecker щільно поєднується з нашим TextEditor класом, що означає, що наш клас TextEditor залежить від EnglishSpellChecker або іншими словами EnglishSpellCheker є залежністю для TextEditor. Нам потрібно зняти цю залежність. Крім того, нашому текстовому редактору потрібен спосіб утримувати конкретну посилання будь-якої перевірки орфографії, заснованої на розсуд розробника на час виконання.

Отже, як ми бачили у введенні DI, це говорить про те, що клас слід вводити залежно від його залежності. Отож, за викликовим кодом має бути відповідальність впроваджувати всі залежності до виклику класу / коду. Тож ми можемо реструктурувати наш код як

interface ISpellChecker
{

    Arraylist<typos> CheckSpelling(string Text);

}

Class EnglishSpellChecker : ISpellChecker

{

    public override Arraylist<typos> CheckSpelling(string Text)

    {

        //All Magic goes here.

    }

}



Class FrenchSpellChecker : ISpellChecker

{

    public override Arraylist<typos> CheckSpelling(string Text)

    {

        //All Magic goes here.

    }

}

У нашому прикладі клас TextEditor повинен отримати конкретний екземпляр типу ISpellChecker.

Тепер залежність може бути введена в Constructor, Public Properties або метод.

Давайте спробуємо змінити наш клас за допомогою Constructor DI. Змінений клас TextEditor буде виглядати приблизно так:

Class TextEditor

{

    ISpellChecker objSpellChecker;

    string Text;



    public void TextEditor(ISpellChecker objSC)

    {

        objSpellChecker = objSC;

    }



    public ArrayList <typos> CheckSpellings()

    {

        return objSpellChecker.CheckSpelling();

    }

}

Так що код виклику під час створення текстового редактора може вводити відповідний SpellChecker Type в екземпляр TextEditor.

Повну статтю ви можете прочитати тут


1

Традиційним способом отримання екземпляра адреси в Employee було б, створивши новий екземпляр class address.Spring створює всі залежні об'єкти, тож нам не потрібно турбуватися про об'єкт.

Отже, навесні ми просто залежаємо від пружинного контейнера, який забезпечує нам об'єкт залежності.


1

МОК - це техніка, коли ви дозволяєте комусь іншому створити предмет для вас. А ще хтось у випадку весни - це контейнер МОК.

Ін'єкція залежності - це техніка, коли один об'єкт забезпечує залежність іншого об'єкта.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.