Принцип інверсії залежності: Як визначити "політику високого рівня" та "деталізацію низького рівня" для інших людей?


13

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

Відповіді:


11

Примітка. Це було повністю переписано з мого попереднього прикладу

Подумайте про розетки. У будь-якій країні, політика високого рівня полягає в тому, що розетки завжди однакові. Не має значення, звідки ви отримуєте електроенергію (вугілля, газ, ядер), розетки на стіні завжди повинні виводити однакову кількість живлення через один і той же набір роз'ємів.

Тепер ви можете підключити будь-який пристрій до цієї розетки, оскільки всі вони мають спільний інтерфейс - «штекер». Політика високого рівня ніколи не повинна диктувати будь-яку частину цієї деталі реалізації. Просто підключіть щось, і воно піде.

Тепер, якщо у вас є пристрій, який не бажає живлення змінного струму - можливо, він працює в ланцюзі 7 В постійного струму - ви все одно можете використовувати цю політику високого рівня, вам просто потрібен якийсь адаптер між джерелом живлення та пристроєм. І оскільки у всіх є однакова політика високого рівня, виробник може вбудовувати це в реалізацію, не змінюючи політику високого рівня. Особі, яка підключає реалізацію до політики (ви, підключаючи ноутбук), насправді не потрібно розуміти.

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

Це ідеальний приклад інверсії залежності.

Але ось цікавий біт: Поверніться до того, що я спочатку сказав. "Не має значення, звідки ви отримуєте електроенергію". Це також детальна інформація про реалізацію. Політика високого рівня все ще полягає в тому, що всі розетки мають однакову форму і випромінюють один і той же тип живлення. Подробиці впровадження на низькому рівні - це і те, звідки надходить електроенергія, і від чого вона працює.

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

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


+1 Crikey. Не знав, що я можу так багато навчитися з простого розетки :)
dreza

7

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

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

Отже, назва "інверсія залежності" дещо вводить в оману - оскільки залежності не "перевернуті", а повністю усунені (а якщо бути точніше: змінені з часу складання залежностей часу компіляції в залежності від часу виконання).


1
Не зовсім. Інверсія відбувається тому, що нижчі рівні приймають залежність від інтерфейсу. Застосовуючи принцип розбиття інтерфейсу (I в SOLID), цей інтерфейс "належить" клієнту. Тож нижчий рівень метафорично приймає залежність від клієнта.
Майкл Браун

2
@MikeBrown: це одна з можливих точок зору. Я віддаю перевагу точці зору, коли інтерфейс не належить ні до А, ні до В, але до інфраструктури чи середовища A і B.
Doc Brown

1

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

Замість того, щоб вищі шари сиділи на нижніх шарах, вищі шари в мобільному інтерфейсі з нижніми шарами через рядок, який їх з'єднує. Певним чином, нижчі шари залежать від інтерфейсу для підтримки (без рядка, який вони впали б). Це DIP в двох словах.


+1 для приємного порівняння. На цьому малюнку ви можете побачити мою думку - всі шари залежать від інтерфейсів, але не нижчі шари на більш високих або навпаки.
Док Браун

Я бачу, що ви говорите, Інтерфейс не належить ні до вищого, ні до нижчого рівня.
Майкл Браун

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

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