← Назад к вопросам

Какие используешь паттерны разработки?

2.0 Middle🔥 202 комментариев
#Паттерны проектирования

Комментарии (2)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Мои ключевые паттерны разработки в Unity

Как senior Unity-разработчик с более чем 10-летним опытом, я сознательно использую архитектурные паттерны для создания масштабируемых, поддерживаемых и тестируемых проектов. Паттерны — это не догма, а инструменты, которые я выбираю в зависимости от задачи.

Основные архитектурные паттерны

  1. Компонентный подход (Component Pattern)
    Это основа самой Unity, и я следую ей в своем коде. Я создаю небольшие, переиспользуемые скрипты, каждый из которых отвечает за одну четкую обязанность. Например, отдельные компоненты для передвижения, здоровья, инвентаря и взаимодействия.

```csharp
// Пример компонента для простого перемещения
public class MovementComponent : MonoBehaviour
{
    [SerializeField] private float _speed = 5f;

    public void Move(Vector2 direction)
    {
        Vector3 movement = new Vector3(direction.x, 0, direction.y) * (_speed * Time.deltaTime);
        transform.Translate(movement);
    }
}
```

2. Наблюдатель (Observer Pattern / Event-driven architecture)

    Я активно использую события (`Action`, `UnityEvent`, `C# events`) для создания слабосвязанных систем. Это позволяет объектам реагировать на изменения, не имея прямых ссылок друг на друга. Например, система UI подписывается на событие `OnHealthChanged`, чтобы обновить полоску здоровья, не зная, какой именно объект его изменил.

```csharp
// Пример использования событий
public class PlayerHealth : MonoBehaviour
{
    public event Action<int> OnHealthChanged; // C# event
    [SerializeField] private UnityEvent OnPlayerDied; // UnityEvent для настройки в инспекторе

    private int _currentHealth = 100;

    public void TakeDamage(int damage)
    {
        _currentHealth -= damage;
        OnHealthChanged?.Invoke(_currentHealth); // Уведомляем подписчиков

        if (_currentHealth <= 0)
        {
            OnPlayerDied?.Invoke();
        }
    }
}
```

Продвинутые архитектурные решения

  1. Сервис-локатор (Service Locator)
    Для глобально доступных менеджеров (Audio, GameState, Input) я часто использую упрощенный сервис-локатор или статический доступ. Однако применяю его осторожно, чтобы не создать "магические" зависимости.

```csharp
// Простейшая реализация сервис-локатора
public static class AudioService
{
    private static IAudioPlayer _player;
    public static void Register(IAudioPlayer player) => _player = player;
    public static void PlaySound(AudioClip clip) => _player?.Play(clip);
}

// Использование из любого места:
AudioService.PlaySound(_explosionClip);
```

4. Состояние (State Pattern)

    Для сложного поведения, такого как AI врага, анимации персонажа или жизненный цикл игры (Меню, Игра, Пауза), я реализую паттерн Состояние. Это делает код чище и избавляет от гигантских `switch`-блоков.

```csharp
// Пример интерфейса состояния
public interface IPlayerState
{
    void Enter(PlayerController player);
    void Update();
    void Exit();
}

public class RunningState : IPlayerState
{
    public void Enter(PlayerController player) { /* Включить анимацию бега */ }
    public void Update() { /* Обработка логики бега */ }
    public void Exit() { /* Остановить анимацию */ }
}
```

5. Инъекция зависимостей (Dependency Injection)

    Для повышения тестируемости и уменьшения связности в крупных проектах я внедряю зависимости через конструктор или публичные поля (настраиваемые в инспекторе Unity). Это позволяет, например, легко подменить реальный источник данных на мок-объект в юнит-тестах.

Когда и зачем я их применяю:

  • Для UI и реактивностиObserver (события) и MVVM (чебиндинг через UniRx или Unity Atoms).
  • Для геймплея и AIКомпоненты, Состояния и Команды (для системы отмены действий или очереди задач).
  • Для архитектуры приложенияСервис-локатор для глобальных сервисов, Инъекция зависимостей для связей между системами, Фабрика для создания сложных объектов.
  • Для данныхSingleton (осторожно!) или ScriptableObject для хранения настроек и конфигураций.

Мой главный принцип — прагматизм. Я не стремлюсь впихнуть все паттерны в один проект. Сначала я оцениваю масштаб, сроки и команду, а затем выбираю минимально необходимый набор паттернов, который обеспечит качество кода сегодня и не заблокирует развитие проекта завтра. Например, для прототипа или джема подойдет простая компонентная архитектура с событиями, а для долгосрочной live-игры с большой командой уже потребуется более строгая архитектура с четким разделением ответственности.

Какие используешь паттерны разработки? | PrepBro