В чем разница между Service Locator и DI

Ответ

Service Locator и Dependency Injection (DI) — оба подхода для управления зависимостями, но работают по-разному.

Service Locator — это контейнер, который предоставляет зависимости по запросу (через явный вызов). Клиентский код сам запрашивает нужный сервис.
Пример:

val service = ServiceLocator.getService<MyService>()

DI — зависимости передаются в класс извне (через конструктор, методы или поля). Класс не знает, как их получить.
Пример:

class MyViewModel(private val repo: MyRepository) { ... }

Ключевые отличия:

  1. Явность — Service Locator скрывает зависимости (их сложнее отследить), DI делает их явными.
  2. Тестируемость — DI упрощает мокирование, так как зависимости легко подменить.
  3. Инверсия управления — DI строже следует принципу IoC.

Вывод: DI предпочтительнее из-за прозрачности и тестируемости, но Service Locator иногда удобен для legacy-кода.

Ответ 18+ 🔞

Давай разберём эту тему, а то некоторые до сих пор путают, как будто на дворе 2002-й год. Service Locator и Dependency Injection — это, конечно, оба про зависимости, но работают они, блядь, с точностью до наоборот, как вилка в глаз или в жопу.

Service Locator — это такой хитрый ящик, куда всё засунули, а ты потом в нём шаришься. Нужен тебе сервис? Сам лезь и доставай, явно проси. Это как прийти в бар и орать: «Эй, дайте мне водки!». Код выглядит примерно так:

val service = ServiceLocator.getService<MyService>()

Видишь? Ты прямо говоришь: «Локатор, дай мне сервис!». И он тебе его даёт. Просто? Да. Но потом, когда ты пытаешься понять, откуда у твоего класса взялась эта зависимость, начинается пиздец. Она спрятана, как манда с ушами. Подозрение ебать чувствую к такому коду.

А Dependency Injection (DI) — это уже другая философия, чувак. Тут тебе не нужно ничего просить. Ты просто заявляешь: «Я хочу вот это!», а тебе это аккуратно подкладывают в конструктор, в поле или в метод. Сам класс нихуя не знает, откуда это взялось. Примерно так:

class MyViewModel(private val repo: MyRepository) { ... }

Смотри — репозиторий просто прилетает в класс, как посылка. Класс его использует и даже не парится, кто и как его создал. Красота!

Так в чём же, блядь, разница, спросишь ты?

  1. Явность против скрытности. С локатором зависимости спрятаны, как хитрая жопа. Чтобы их отследить, надо по коду ползать. В DI же всё на виду — открыл конструктор и сразу видишь, на чём класс держится. Доверия к такому коду — овердохуища.
  2. Тестируемость. Вот тут DI просто пизда рулю. Хочешь протестировать MyViewModel? Да похуй! Просто подсуни ей в конструктор мок-репозиторий, и всё. С локатором же придётся этот самый локатор настраивать, подменять, и в итоге получается ёперный театр.
  3. Инверсия управления. DI следует этому принципу жёстко и чётко. Класс не управляет своими зависимостями — за него это делает внешний мир. Локатор — это уже какая-то полумера, полупидор.

Вывод, блядь, простой. DI — это современный, прозрачный и тестируемый подход. Его и используй. Service Locator — это такой костыль, который иногда выручает в старом, кривом легаси-коде, где всё уже накрылось медным тазом и переписать всё с нуля — та ещё история. Но для нового проекта даже не думай — бери DI и живи спокойно.