Когда проект перерастает пару сцен, рано или поздно встаёт вопрос: как организовать доступ к общим сервисам: звуку, аналитике, данным игрока?
Два самых распространённых ответа это 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_люминатор