Этот обзор посвящен анализу кода проекта space shooter. Код характеризуется особенностями, связанными с обстоятельствами его создания. Основное внимание уделено архитектурным аспектам и организации кода.
Структура проекта
Структура проекта нелогична. Весь код и ресурсы сосредоточены в подпапке _ScrollShooter. Эффективнее выделить отдельные папки для однородных элементов, например, для абстракций над Unity и геймплейной логики. Наличие папок ScrollShooter и _ScrollShooter избыточно. Назначение папок smash и standard_assets неясно, их расположение в корне проекта неудачно.
Отсутствует абстракция над движком Unity. Весь код использует терминологию Unity (папка Scripts, префиксы sash и ss). Более логичная структура, например, разделение на компоненты и системы, отсутствует. Папка Components не обоснована и не следует принципам проектирования.
Не соблюдаются SOLID принципы, отсутствует подготовка к unit-тестированию.
Настройка объектов игры
Настройка объектов игры в редакторе осуществляется через сцену, использующую внешние ресурсы. Однако, смешение данных и логики из-за отсутствия разделения слоёв абстракции. Настройка происходит через скрипты и объекты в папке Resources/Data, включая ShooterLogic. Дизайнер может создавать и изменять корабли, астероиды и т.д. Подробный анализ настроек невозможен из-за отсутствия компиляции проекта.
Анемичная модель и процедурный стиль
Используется анемичная модель: данные и методы разделены. Сущности — объекты, содержащие только поля; логика реализована процедурно через сервисы. Хотя в некоторых местах используется делегирование и передача объектов, общая картина остаётся процедурной.
Проекция объектов и работа с данными
Представление объектов как проекции на файловую систему и оперативную память создаёт сложности в работе с данными и графом компонентов. Необходимо формализовать преобразование объектов в граф компонентов и обратно. В текущей реализации смешиваются создание объектов и работа с ними (например, в методе BuildData). Использование BuildData в компоненте Asteroid для распределения данных некорректно.
Обработка столкновений
Обработка столкновений неэффективна. Замена проверки ссылки на компонент на вызов функции не решает проблему. Предложено использовать роутинг сообщений Unity, выделив логику нанесения урона в отдельную функцию. Необходимо скрыть вызов GetComponent для повышения читаемости и производительности.
Названия компонентов и структура данных
Названия компонентов часто не отражают их функции (например, BuildComponent включает загрузку и распределение данных). Использование имён Controller, Manager не всегда оправдано. Более точные имена (например, AsteroidLoader) повысят читаемость. Взаимодействие с данными неформализовано, что приводит к дублированию кода (например, в Asteroid и Spaceship). Выделение загрузчика и использование шаблонов стратегий сократит код.
Работа с UI и презентерами
Использование презентеров (IosPresenter, ScorePresenter) неэффективно. Вместо визуализации сущностей созданы одноимённые утилиты, усложняющие архитектуру. Использование FindObjectOfType некорректно, так как приводит к нетипизированному контейнеру и сложностям в конфигурировании.
Зависимости и модульность
Отсутствует ясное определение зависимостей. FindObjectOfType приводит к нетипизированному контейнеру и ошибкам конфигурирования. Это усложняет тестирование. Проект нуждается в модульности для независимого тестирования объектов. Отсутствие интерфейсов и формализма приводит к многочисленным проблемам.
Проект демонстрирует попытку создания архитектуры, но без должного внимания к деталям и принципам проектирования. Отсутствует разделение ответственности, смешаны слои абстракции, используется неэффективная обработка данных и зависимостей. Для улучшения необходимо выделить компоненты, скрыть сложности загрузчика, избегать FindObjectOfType, использовать шаблоны проектирования и создать формализованный интерфейс взаимодействия между компонентами. Проект нуждается в существенной переработке архитектуры и организации кода.