Здається, існує велика плутанина щодо структури інверсії управління (IoC). Чимало людей прирівнюють його до Стратегічної моделі або Компонентної моделі, але ці порівняння насправді не фіксують те, про що йдеться у IoC. IoC - це справді про те, як виходить залежність. Дозвольте навести приклад:
class Game {
void Load() {
this.Sprite.Load(); // loads resource for drawing later
}
}
class Sprite {
void Load() {
FileReader reader = new FileReader("path/to/resource.gif");
// load image from file
}
}
У вищесказаному зрозуміло, що Sprite.Load
має залежність від a FileReader
. Коли ви хочете перевірити метод, вам потрібно наступне:
- Файлова система на місці
- Тестовий файл для завантаження з файлової системи
- Можливість ініціювати поширені помилки файлової системи
Перші два очевидні, але якщо ви хочете переконатися, що обробка помилок працює так, як очікувалося, вам теж потрібен номер 3. В обох випадках ви потенційно сповільнили свої тести, тому що тепер потрібно перейти на диск, і ви, ймовірно, ускладнили тестувальне середовище.
Мета IoC - відключити використання поведінки від її побудови. Зверніть увагу, чим це відрізняється від структури Стратегії. Завдяки шаблону стратегії мета полягає в тому, щоб закріпити повторно використаний шматок поведінки, щоб ви могли легко поширити її в майбутньому; він не має нічого сказати про те, як будуються стратегії.
Якби ми переписали Sprite.Load
метод вище, ми, швидше за все, закінчимося:
class Sprite {
void Load(IReader reader) {
// load image through reader
}
}
Тепер ми розв'язали конструкцію читача від його використання. Тому під час тестування можна поміняти місцями тестового зчитувача. Це означає, що вашому тестувальному середовищу більше не потрібна файлова система, тестові файли та ви можете легко імітувати події помилок.
Зауважте, що я переписав дві речі. Я створив інтерфейс, IReader
який інкапсулював деяку поведінку - тобто реалізував шаблон стратегії. Крім того, я переклав відповідальність за створення потрібного читача на інший клас.
Можливо, нам не потрібна нова назва шаблону, щоб описати вище. Мене це вражає як поєднання стратегій та заводських моделей (для контейнерів IoC). Попри це, я не впевнений, на якій підставі люди заперечують проти цієї картини, оскільки зрозуміло, що вона вирішує справжню проблему, і, звичайно, мені не очевидно, що це стосується Java.