Нещодавно я прочитав статтю Марка Семана про антидіапазон службового пошуку.
Автор вказує на дві основні причини, по яких ServiceLocator є антидіаграмою:
Проблема використання API (з якою я прекрасно вживаюсь)
Коли клас використовує сервіс-локатор, дуже важко помітити його залежності, оскільки, в більшості випадків, клас має лише один конструктор PARAMETERLESS. На відміну від ServiceLocator, підхід DI явно виставляє залежності за допомогою параметрів конструктора, тому залежності легко помітити в IntelliSense.Проблема з обслуговування (що мене
спантеличує ) Розглянемо наступний приклад
У нас є клас "MyType", який використовує підхід до локатора сервісів :
public class MyType
{
public void MyMethod()
{
var dep1 = Locator.Resolve<IDep1>();
dep1.DoSomething();
}
}
Тепер ми хочемо додати ще одну залежність до класу "MyType"
public class MyType
{
public void MyMethod()
{
var dep1 = Locator.Resolve<IDep1>();
dep1.DoSomething();
// new dependency
var dep2 = Locator.Resolve<IDep2>();
dep2.DoSomething();
}
}
І ось тут починається моє непорозуміння. Автор каже:
Ставати набагато важче сказати, чи вносите ви переломну зміну чи ні. Вам потрібно зрозуміти всю програму, в якій використовується Локатор послуг, а компілятор вам не допоможе.
Але зачекайте секунду, якби ми використовували підхід DI, ми запровадили б залежність від іншого параметра в конструкторі (у випадку введення конструктора). І проблема все одно буде. Якщо ми можемо забути налаштувати ServiceLocator, то ми можемо забути додати нове відображення в наш контейнер IoC, і підхід DI матиме таку ж проблему під час виконання.
Також автор згадував про складнощі тестування одиниць. Але чи не буде у нас проблем із підходом до DI? Чи не потрібно нам оновлювати всі тести, які створювали цей клас? Ми оновимо їх, щоб пройти нову глузувальну залежність просто для того, щоб зробити тест комбінованим. І я не бачу ніякої користі від цього оновлення та витрат часу.
Я не намагаюся захищати підхід до служби Locator. Але це непорозуміння змушує мене думати, що я втрачаю щось дуже важливе. Чи може хтось розвіяти мої сумніви?
ОНОВЛЕННЯ (РЕЗЮМЕ):
Відповідь на моє запитання "Чи є Locator сервісу анти-шаблоном" дійсно залежить від обставин. І я точно не пропоную викреслити це зі списку інструментів. Це може стати дуже зручним, коли ви почнете мати справу зі застарілим кодом. Якщо вам пощастило опинитися на самому початку вашого проекту, то підхід DI може бути кращим вибором, оскільки він має деякі переваги перед службою пошуку.
І ось основні відмінності, які переконували мене не використовувати Локатор послуг для моїх нових проектів:
- Найбільш очевидне та найважливіше: Локатор послуг приховує залежність класів
- Якщо ви використовуєте якийсь контейнер IoC, він, швидше за все, сканує весь конструктор при запуску, щоб перевірити всі залежності і дасть вам негайний зворотній зв’язок про відсутні відмітки (або неправильну конфігурацію); це неможливо, якщо ви використовуєте контейнер IoC в якості сервера пошуку
Детальніше читайте чудові відповіді, які наведені нижче.