Інверсія управління
Інверсія керування (англ. Inversion of Control, IoC) — це принцип побудови програми, при якому її частини отримують потік керування (викликаються) із загальної спільновикористовуваної бібліотеки. Це ніби звичайне процедурне програмування вивернуте навиворіт (inversed). Також це називають «голлівудським принципом»: «Не дзвоніть нам, ми подзвонимо вам».
Однією з реалізацій IoC є впровадження залежностей (англ. Dependency Injection), що використовується в багатьох фреймворках, вони називаються IoC контейнери. Використовуються в таких об'єктно-орієнтованих мовах програмування, як Smalltalk, C++, Java, PHP або мови платформи .NET.
Огляд
Наприклад, у випадку традиційного програмування, головна функція програми може викликати функцію із бібліотеки, щоб відобразити список доступних команд, і запросити користувача вибрати одну з них.[1] Бібліотека поверне вибрану опцію як результат виклику функції. Цей стиль використовувався у текстових інтерфейсах. Наприклад, поштовий клієнт може показати екран з командами для завантаження нових листів, відповіді на поточний лист, розпочати новий лист і т. д., а виконання програми буде заблоковане допоки користувач не натисне клавішу, щоб обрати команду.
Натомість, у випадку інверсії управління, програма пишеться із використанням програмного каркаса, який знає загальні поведінкові і графічні елементи, такі як віконний інтерфейс, меню, керування мишкою тощо. Користувацький код «заповнює пробіли» у каркасі, такі як надавання таблиці елементів меню і реєстрація підпрограм для кожного елемента, але відслідковування дій користувача і виклик пов'язаної підпрограми є завданням каркаса. У прикладі поштового клієнта, каркас може слідкувати за клавіатурою і мишкою і викликати команду, обрану користувачем, також одночасно з цим моніторити мережевий інтерфейс, щоб помітити прибуття нового повідомлення і оновити екран коли з'являється мережева активність. Цей самий каркас можна використати як скелет для програми електронних таблиць або текстового редактора. З іншого боку, каркас нічого не знає про веб-оглядачі, електронні таблиці, текстові редактори; втіленням їх функціональності займається користувацький код.
Інверсія управління несе важливу ідею, що повторно використовний код і завдання-залежний код розробляються незалежно, хоча й діють разом. Програмні каркаси, callback'и, планувальники, цикли подій і впровадження залежностей є прикладами шаблонів, що слідують принципу інверсії управління, хоча термін найчастіше вживається в контексті ООП.
Принцип інверсії залежностей
Модулі верхніх рівнів не повинні залежати від модулів нижчих рівнів. Обидва типи модулів повинні залежати від абстракцій. Абстракції не повинні залежати від деталей. Деталі повинні залежати від абстракцій.
Клас X залежить від класу Y, якщо виконується одна з наступних умов:
- X містить (has-a) Y
- X є (is-a) Y
- X залежить від деякого класу Z, який залежить від Y (принцип транзитивності)
X залежить від Y не означає, що Y залежить від X. Якщо ж існують обидві залежності, то це називається циклічною залежністю: X не може бути використаний без Y, та навпаки. Існування великого числа циклічних залежностей в об'єктно-орієнтованій програмі може бути показником неоптимальної будови програми.
Розрив залежності
Якщо об'єкт x (класу X) викликає методи об'єкту y (класу Y), то X залежить від Y. Залежність може бути звернена створенням третього класу, а саме інтерфейсного класу I, який повинен містити в собі усі методи, які x може викликати у об'єкта y. Крім того, Y повинен реалізовувати інтерфейс I. X та Y наразі обидва залежать від I, і клас X більш не залежить від класу Y; передбачається, що X не реалізує I.
Це виключення залежності класу X від Y шляхом створення інтерфейсу I і називається Inversion of Control.
Слід сказати, що Y може залежати від інших класів. До внесення змін X залежав від Y, тоді X побічно залежав від усіх класів, від яких залежить Y. За допомогою застосування Inversion of Control всі побічні залежності були розірвані — не тільки залежність X від Y.
Застосування IoC контейнерів
C++
Java
Програмісти, які використовують Java застосовують Inversion of Control в Inversion of Control контейнерах. Програмне забезпечення робить запит на об'єкт з контейнера, та контейнер створює об'єкт та його залежності. Сервер программ ATG Dynamo був одним з перших обчислювальних середовищ, які ефективно використовували цей підхід. Сучасні приклади IoC-контейнерів: HiveMind, PicoContainer, Spring Framework (Spring — повноцінна корпоративна платформа, а не тільки IoC-контейнер), Apache Excalibur, Seasar, и DPML Metro.
PHP4
Python
Примітки
Посилання
- Максим Базь. SOLID'не проєктування: принцип інверсії залежностей[недоступне посилання з червня 2019](рос.)