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

Какие знаешь GoF паттерны?

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

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

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

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

Шаблоны проектирования GoF (Gang of Four)

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

Порождающие паттерны (Creational)

Эти паттерны отвечают за создание объектов, что критически важно в Unity для управления памятью и производительности.

  • Singleton (Одиночка) — возможно, самый распространённый в Unity. Используется для глобальных менеджеров (GameManager, AudioManager, UIManager). Однако важно реализовывать его осторожно, избегая глобального состояния там, где можно использовать инъекцию зависимостей.

    public class GameManager : MonoBehaviour
    {
        public static GameManager Instance { get; private set; }
    
        private void Awake()
        {
            if (Instance != null && Instance != this)
                Destroy(gameObject);
            else
                Instance = this;
    
            DontDestroyOnLoad(gameObject);
        }
        // ... остальная логика
    }
    
  • Factory Method (Фабричный метод) & Abstract Factory (Абстрактная фабрика) — незаменимы для создания сложных объектов, например, разных типов врагов, снарядов или UI-элементов. Позволяют отделить логику создания от основной игровой логики.

  • Builder (Строитель) — полезен для пошагового создания сложных конфигураций объектов, например, кастомных персонажей или уровней.

  • Prototype (Прототип) — в Unity реализован "из коробки" через префабы. Клонирование префаба – это и есть использование паттерна Прототип.

    // Создание экземпляра префаба – реализация Prototype
    GameObject newEnemy = Instantiate(enemyPrefab, spawnPosition, Quaternion.identity);
    

Структурные паттерны (Structural)

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

  • Adapter (Адаптер) — используется для интеграции сторонних SDK или библиотек, интерфейс которых не совместим с вашим кодом.
  • Composite (Композиция) — основа иерархической системы GameObject-Transform в Unity. Каждый GameObject может содержать коллекцию других GameObject, и с ними можно работать единообразно.
  • Decorator (Декоратор) — теоретически применим для динамического добавления поведения объектам. На практике в Unity его роль часто играют MonoBehaviour компоненты, которые можно "навешивать" на объекты, чтобы расширять их функциональность.
  • Facade (Фасад) — создаёт простой интерфейс к сложной подсистеме. Например, AudioManager.Instance.PlaySound("Shoot") скрывает внутри себя работу с AudioSource, пулом объектов и настройками громкости.
  • Proxy (Заместитель) — может использоваться для ленивой инициализации тяжелых ресурсов (например, ассетов) или для контроля доступа к системам.

Поведенческие паттерны (Behavioral)

Управляют алгоритмами, распределением обязанностей и взаимодействием между объектами.

  • Observer (Наблюдатель) — фундаментальный паттерн в игровой разработке. В C# он реализован через механизм событий (events и делегаты action). В Unity также есть встроенная поддержка через UnityEvent.

    public class PlayerHealth : MonoBehaviour
    {
        public event Action<float> OnHealthChanged; // Подписываемся на это событие из UI
        public event Action OnPlayerDied;
    
        private float _currentHealth;
    
        public void TakeDamage(float damage)
        {
            _currentHealth -= damage;
            OnHealthChanged?.Invoke(_currentHealth); // Уведомляем всех подписчиков
    
            if (_currentHealth <= 0)
                OnPlayerDied?.Invoke();
        }
    }
    
  • State (Состояние) — исключительно важен для управления поведением игровых сущностей: состояния персонажа (Idle, Run, Attack, Die), состояния игры (Menu, Playing, Paused). Позволяет избежать гигантских switch-блоков и делает код чистым.

  • Strategy (Стратегия) — используется для определения семейства алгоритмов (например, различных типов движения AI, способов расчёта урона) и их взаимозаменяемости.

  • Command (Команда) — полезен для реализации системы отмены действий (undo/redo), записи повторов или организации очереди задач. Часто применяется в управлении (input).

  • Iterator (Итератор) — встроен в C# (foreach). Активно используется для прохода по коллекциям объектов игры.

Заключение и рекомендации для Unity

Знание паттернов – это не цель, а инструмент для решения конкретных проблем архитектуры. В Unity нельзя применять их механически, не учитывая специфику движка:

  1. Система компонентов (ECS-like в MonoBehaviour) сама по себе является композицией паттернов Компонент и Наблюдатель.
  2. Не все "классические" реализации применимы напрямую из-за жизненного цикла MonoBehaviour и требований к производительности.
  3. Важно не перегружать проект паттернами. Иногда простая ссылка на компонент в инспекторе ([SerializeField] private EnemySpawner _spawner) эффективнее сложной абстрактной фабрики.

Грамотное применение GoF-паттернов в Unity приводит к созданию кода, который легче тестировать, отлаживать и расширять на протяжении всего жизненного цикла проекта, что критически важно как для небольших инди-игр, так и для крупных AAA-тайтлов.

Какие знаешь GoF паттерны? | PrepBro