Я розробляю нову систему і хочу знати, що таке інверсія управління (МОК), і що ще важливіше, коли її використовувати.
Чи потрібно його реалізовувати за допомогою інтерфейсів чи це можна зробити з класами?
Я розробляю нову систему і хочу знати, що таке інверсія управління (МОК), і що ще важливіше, коли її використовувати.
Чи потрібно його реалізовувати за допомогою інтерфейсів чи це можна зробити з класами?
Відповіді:
IoC (див. Інверсія контролю у Вікіпедії) застосовується в тих випадках, коли компонент не може виконувати завдання повністю, оскільки не має певної необхідної інформації або функціоналу.
Найпростішим прикладом шаблону IoC можуть бути функції зворотного виклику в C. Наприклад, ви можете оголосити функцію:
void Iterator(void *list, Func* f)
Що повторює list
застосування f
функції до кожного її елемента. Iterator
Функція не знає , як буде оброблятися кожен елемент, ви просто вказати функцію в якості аргументу, і він обробляє їх.
Як показано в попередньому прикладі, IoC дозволяє розділити свою програму на окремі компоненти, які не знають один про одного. Однією з найпоширеніших версій IoC є Dependecy Injection .
В ін'єкційній залежності кожний компонент повинен оголосити перелік залежностей, необхідних для виконання його завдання. Під час виконання спеціальний компонент (як правило) під назвою контейнер IoC здійснює зв'язок між цими компонентами. Він намагається надати значення для опублікованих залежностей компонентів.
Ось приклад у псевдокоді:
class Foo
{
<Require Boo>Constructor(Boo boo){ boo.DoSomething }
}
У цьому прикладі клас Foo
має конструктор, який вимагає аргументу типу Boo
для виконання певної дії.
Ви можете створити екземпляр класу, Foo
використовуючи код, подібний цьому:
MyContainer.Create(typeof Foo)
MyContainer
- це контейнер IoC , який піклується про отримання екземпляра Boo
та передачу його Foo
конструктору.
Підводячи підсумок, IoC дозволяє розділити свою програму на окремі частини. Це добре тому, що:
Однак в деяких випадках IoC може зробити складніше зрозумілий код.
Якщо ви хочете побачити хороший приклад використання IoC в реальному світі , перегляньте блок прикладних інтерфейсів Mircosoft Composite та CompositeWPF
Сподіваюся, моє пояснення вам допоможе.
З повагою,
аку
Оскільки я нещодавно сам займався цим питанням і зберігав усі закладки, я дізнався наступне, щоб дізнатися про IOC / DI.
Оригінальна стаття Мартіна Фаулерса про IOC / DI
Деякі поняття, які слід знати спочатку
Відмінна колекція навчальних посібників з МОК / DI
Книга про МОК / DI від Manning Press
Джерело та пояснення того, як створити власний МОК - адже читання вихідного коду - це завжди найкращий спосіб зрозуміти поняття.
Привіт, JMS, в основному IoC / DI дозволить вам визначити, яку реалізацію ви використовуєте один раз, і зберегти статичну копію вашого контейнера для посилання кожного разу, коли ви хочете посилатися на нього.
Вікіпедія, ймовірно, допоможе вам, але я хотів посилатися на вашу другу частину - так, введення залежностей можна робити для класів (тобто, кожного разу, коли цей тип класу потрібно передати методу, використовувати цей клас), але краще використовуйте інтерфейси, тому що таким чином ви можете змінити версію постачальника, сховища тощо, яку ви використовуєте, просто перепосилавшись на неї у вашому налаштуванні.
IE, скажімо, у вас був інтерфейс для читання потоку, і у вас була реалізація XMLStreamReader та SQLStreamReader. Потім ви можете передати посилання на інтерфейс до своїх методів, а потім у своєму контейнері IoC сказати, який саме використовувати.
Отже, у вас може бути відкритий список ReadPeople (читач IStreamReader) і під час налаштування для вашого контейнера IoC повідомте про це кожен раз, коли ви очікуєте, що IStreamReader використовуватиме SQLStreamReader.
Тоді, якщо згодом ви передумаєте, вам потрібно змінити це лише в одному місці (налаштування вашого контейнера), і не важливо буде, скільки методів вимагає IStreamReader, він завжди отримає стандартний стандарт, про який ви сказали своєму контейнерові служити
Скажімо, у вас є валідатор для перевірки того, чи дійсний бізнес у вашій системі. Ваш "BusinessValidator" може мати поле типу AddressValidator, яке підтверджує адресу адреси бізнесу. Якщо ви хочете протестувати BusinessValidator, не виконуючи зовнішній код (тобто код addressValidator), тоді, якщо ви використовували якийсь IoC / DI у ваших рамках, ви можете ослабити "ввести" макет адресуValidator на своє місце, і не потрібно турбуватися про тестування код за межами тестуваного класу.