В чем различия Service Locator и Dependency Injection?
Продвинутые темы
Service Locator и Dependency Injection — два способа предоставить зависимости: DI внедряет их извне в объект, а Service Locator даёт объекту реестр, откуда он сам запрашивает зависимости.
Dependency Injection (DI)
Зависимости передаются объекту извне (через конструктор/параметры). Объект не знает, откуда они берутся:
class UserService {
constructor(api) { // зависимость внедрена
this.api = api;
}
}
new UserService(httpApi);Зависимости явные (видны в сигнатуре).
Service Locator
Объект сам запрашивает зависимости из глобального реестра (локатора):
class UserService {
constructor() {
this.api = ServiceLocator.get('api'); // сам достаёт
}
}Зависимости скрытые (не видны снаружи).
Различия
- Направление: DI — зависимости приходят извне («push»); Service Locator — объект их достаёт («pull»).
- Явность: DI — зависимости явные в сигнатуре; Service Locator — скрытые внутри.
- Тестируемость: DI проще тестировать (подставить мок в конструктор); Service Locator требует настройки глобального реестра.
- Связанность: Service Locator создаёт скрытую зависимость от самого локатора.
Почему DI обычно предпочтительнее
Явные зависимости, лучше тестируемость, нет глобального состояния. Service Locator считают антипаттерном во многих случаях из-за скрытых зависимостей.
Коротко для собеседования
DI внедряет зависимости извне (через конструктор) — явно, тестируемо. Service Locator даёт объекту реестр, откуда он сам достаёт зависимости — скрыто, с зависимостью от локатора. DI предпочтительнее (явность, тестируемость, нет глобального состояния); Service Locator часто считают антипаттерном.