Этот анализ посвящен коду победителя конкурса по разработке игр, проводимого школой программирования Junior. Приз составил 25 000 рублей в номинации «Лучшая игра на движке Unity» и аналогичная сумма за «Лучшую игру с лучшим исходным кодом на Unity». Школа учредила специальные номинации для своих учеников, удваивающие призовые в случае победы. Анализ кода направлен на выявление сильных и слабых сторон и демонстрацию лучших практик.
Об игре
Победитель разработал игру, в которой игрок, предположительно, сбегает из тюрьмы. Выбор победителя осуществил независимый эксперт Алексей Хряков.
Система кэширования
Код использует систему кэширования, вдохновлённую статьёй Валентина Симонова на сайте Unity3D. Вместо стандартного Update в компонентах создаётся собственная система с классом ManaKish (абстрактный класс), от которого наследуются обновляемые компоненты. Это позволяет агрегировать обновление множества объектов, потенциально повышая производительность.
Однако такая оптимизация редко необходима в большинстве проектов, создавая излишнюю сложность с подписками и отписками. Простота и надёжность предпочтительнее при отсутствии явной необходимости в оптимизации. Система кэширования реализована с помощью методов Tick и TickFixed. Добавление и удаление объектов осуществляется статически, что создаёт дополнительные связи и снижает читаемость.
Паттерн Фасад и его реализация
Победитель попытался использовать паттерн Фасад для объединения подсистем. В игре есть игрок (Player), его движение (PlayerMovement), анимация, ввод (PlayerInput) и другие компоненты. Класс Player служит фасадом, предоставляя удобный интерфейс для взаимодействия с подсистемами.
Реализация паттерна Фасад неидеальна. Класс Character, наследующий от ManaKish, используется как базовый для других фасадов (например, Player). В Character присутствуют методы Tick и TickFixed, унаследованные от ManaKish, но сам класс Character имеет мало публичных членов и теряет смысловую нагрузку. Инициализация фасада нестандартна, вызывая вопросы к его функциональности и эффективности.
Улучшения системы кэширования и паттерна Фасад
Предлагается ряд улучшений. Вместо наследования от ManaKish и переопределения Awake в реализации паттерна Фасад, рекомендуется использовать паттерн Шаблонный Метод для создания более устойчивой системы. Необходимо использовать вспомогательные методы для подписки и отписки, а также переосмыслить существующие методы, сделав их более понятными и функциональными.
Пример псевдокода демонстрирует альтернативную реализацию с использованием Шаблонного метода. Это позволит избежать дублирования кода, повысить надёжность и улучшить читаемость.
Улучшение класса Character и использование абстрактной фабрики
Предлагается пересмотреть реализацию класса Character. Вместо абстрактного класса предлагается использовать обычный класс с методом инициализации, избавляясь от избыточного наследования от ManaKish. Также предлагается создать отдельные классы-инсталляторы (Installer) для различных типов персонажей (например, PlayerInstaller, PoliceInstaller), используя паттерн Абстрактная Фабрика для создания объектов. Это позволит избежать параллельно развивающихся иерархий и упростит управление зависимостями. Необходимо добавить идентификаторы для эффективного управления типами объектов.
Код победителя, хотя и не идеален, является лучшим из представленных на конкурс. Предложенные улучшения направлены на повышение качества кода, надёжности, читаемости и упрощения структуры. Анализ помогает понять основные проблемы и предлагает решения, основанные на лучших практиках разработки игр на Unity с использованием C#. Дальнейший анализ кода будет посвящён системе инвентаря.