TGViewer
Библиотека шарписта | C#, F#, .NET, ASP.NET Библиотека шарписта | C#, F#, .NET, ASP.NET @csharpproglib · 21.7K subscribers
Post #6977 2.77K
👨‍💻 Singleton vs Service Locator в Unity

Когда проект перерастает пару сцен, рано или поздно встаёт вопрос: как организовать доступ к общим сервисам: звуку, аналитике, данным игрока?

Два самых распространённых ответа это Singleton и Service Locator. Разберём, чем они отличаются и когда какой уместен.

Singleton

Паттерн знаком почти каждому Unity-разработчику. Один экземпляр класса на всё приложение, доступный из любой точки кода:
public class AudioManager : MonoBehaviour
{
public static AudioManager Instance { get; private set; }

private void Awake()
{
if (Instance != null)
{
Destroy(gameObject);
return;
}
Instance = this;
DontDestroyOnLoad(gameObject);
}

public void PlaySound(AudioClip clip) { /* ... */ }
}


Плюсы:

+ Просто реализовать
+ Мгновенный доступ без регистрации
+ Подходит для небольших проектов

Минусы:

- Жёсткая связность: классы напрямую зависят от конкретной реализации
- Тестировать сложно — нельзя подменить AudioManager на заглушку
- При разрастании проекта Instance начинают тянуть отовсюду, и следить за зависимостями становится тяжело

Service Locator

Service Locator это реестр сервисов. Вместо того чтобы обращаться к конкретному классу, код запрашивает нужный интерфейс у локатора.

Сначала создаём интерфейс:
public interface IAudioService
{
void PlaySound(AudioClip clip);
}


Реализация сервиса:
public class AudioManager : MonoBehaviour, IAudioService
{
public void PlaySound(AudioClip clip) { /* ... */ }
}


Сам локатор:
public static class ServiceLocator
{
private static readonly Dictionary<Type, object> services = new();

public static void Register<T>(T service)
{
services[typeof(T)] = service;
}

public static T Get<T>()
{
if (services.TryGetValue(typeof(T), out var service))
return (T)service;

throw new Exception($"Сервис {typeof(T)} не зарегистрирован");
}
}


Плюсы:

+ Код зависит от интерфейса, а не от реализации
+ Легко подменить сервис на заглушку в тестах
+ Зависимости явно регистрируются в одном месте

Минусы:

- Если забыть зарегистрировать сервис, то получим исключение в рантайме, а не ошибку компиляции
- Чуть больше кода на старте
- Без дисциплины реестр может превратиться в свалку

Когда что выбирать

Singleton оправдан в небольших проектах, где скорость разработки важнее архитектурной чистоты. Прототип, геймджем, или небольшая мобильная игра.

Service Locator стоит рассмотреть, когда проект планируется развивать: появляются юнит-тесты, несколько платформ, команда из нескольких человек. Возможность подменить реализацию без изменения потребителей сервиса окупается уже при первом рефакторинге.

Оба паттерна решают одну задачу — глобальный доступ к сервисам. Разница в том, насколько легко потом менять и тестировать код.

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

#il_люминатор
  • 👍 8
More from @csharpproglib
  1. Sep 23, 2026⚙️ yield return не бесплатный Итераторы выглядят просто, но работают иначе: IEnumerable<in…
  2. Sep 22, 2026💡 Replace, Regex или StringBuilder? Для замены текста в C# есть несколько инструментов. И…
  3. Sep 21, 2026⚙️ Настоящие атомарные операции Если Volatile решает проблему видимости, то Interlocked ре…
  4. Sep 20, 2026💪 Разминка перед трудовыми буднями Что произойдёт? ❤️ — список станет [1, 3] 🔥 — Invalid…
  5. Sep 19, 2026🧩 Middleware в ASP.NET Core: 3 ловушки Middleware — звено HTTP pipeline: app.Use(async (c…
  6. Sep 18, 2026📍 Навигация: Вакансии • Задачи • Собесы 🐸Библиотека шарписта #garbage_collector
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →