Інверсія керування
Інверсія керування (англ. 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++[ред. | ред. код]
- PocoCapsule [Архівовано 24 квітня 2011 у Wayback Machine.]
Java[ред. | ред. код]
Програмісти, які використовують Java застосовують Inversion of Control в Inversion of Control контейнерах. Програмне забезпечення робить запит на об'єкт з контейнера, та контейнер створює об'єкт та його залежності. Сервер программ ATG Dynamo був одним з перших обчислювальних середовищ, які ефективно використовували цей підхід. Сучасні приклади IoC-контейнерів: HiveMind, PicoContainer, Spring Framework (Spring — повноцінна корпоративна платформа, а не тільки IoC-контейнер), Apache Excalibur, Seasar, и DPML Metro.
.NET[ред. | ред. код]
- Unity Application Block 2.0 [Архівовано 24 червня 2011 у Wayback Machine.]
- Spring.NET [Архівовано 2 квітня 2006 у Wayback Machine.]
- Structuremap
- CastleProject [Архівовано 25 червня 2014 у Wayback Machine.]
- Seasar [Архівовано 7 серпня 2011 у Wayback Machine.]
- Winter.NET [Архівовано 3 квітня 2011 у Wayback Machine.]
- Ninject [Архівовано 23 червня 2011 у Wayback Machine.]
PHP4[ред. | ред. код]
- drip [Архівовано 21 серпня 2011 у Wayback Machine.]
PHP5[ред. | ред. код]
- Garden [Архівовано 30 жовтня 2011 у Wayback Machine.]
- Symfony Dependency Injection [Архівовано 6 липня 2011 у Wayback Machine.]
Python[ред. | ред. код]
- zope.interface [Архівовано 12 червня 2011 у Wayback Machine.] і zope.component [Архівовано 11 вересня 2011 у Wayback Machine.]
RUBY[ред. | ред. код]
ActionScript[ред. | ред. код]
- Mate [Архівовано 15 квітня 2022 у Wayback Machine.]
- MIoC [Архівовано 19 лютого 2011 у Wayback Machine.]
- Robotlegs
- Swiz [Архівовано 17 січня 2022 у Wayback Machine.]
- Dawn [Архівовано 9 жовтня 2010 у Wayback Machine.]
Див. також[ред. | ред. код]
Примітки[ред. | ред. код]
- ↑ Dependency Injection [Архівовано 30 травня 2020 у Wayback Machine.].
Посилання[ред. | ред. код]
- Максим Базь. SOLID'не проєктування: принцип інверсії залежностей[недоступне посилання з червня 2019](рос.)
Це незавершена стаття про програмне забезпечення. Ви можете допомогти проєкту, виправивши або дописавши її. |