Реализация общих паттернов проектирования игрового программирования в вашем проекте Unity поможет вам эффективно создавать и поддерживать чистую, организованную и читаемую кодовую базу. Паттерны проектирования сокращают время рефакторинга и тестирования, ускоряя процессы разработки и способствуя созданию прочного фундамента для развития вашей игры, команды и бизнеса.
Воспринимайте паттерны проектирования не как готовые решения, которые можно скопировать и вставить в код, а как дополнительные инструменты, которые помогут вам создавать более крупные и масштабируемые приложения.
На этой странице рассказывается о шаблонах проектирования Model View Controller (MVC) и Model View Presenter (MVP).
Содержание этой статьи основано на бесплатной электронной книге, Повысьте уровень своего кода с помощью паттернов программирования игр.
Ознакомьтесь с другими статьями из серии "Шаблоны проектирования игрового программирования Unity" на хабе " Лучшие практики Unity " или по этим ссылкам:
Вы можете использовать шаблоны проектирования Model View Controller (MVC) и Model View Presenter (MVP), чтобы отделить данные и логику в вашем приложении от способа их представления. В этих паттернах применяются принципы "разделения забот", что позволяет повысить гибкость и ремонтопригодность вашей кодовой базы.
В разработке игр Unity вы можете использовать эти паттерны для разделения логики игры на отдельные компоненты, такие как данные (модель), визуальное представление (вид) и логика, управляющая взаимодействием между ними (контроллер или презентер).
MVC - это семейство шаблонов проектирования, которые обычно используются при разработке пользовательских интерфейсов в программных приложениях.
Общая идея MVC заключается в том, чтобы отделить логическую часть вашего программного обеспечения от данных и представления. Это помогает уменьшить количество ненужных зависимостей и потенциально сократить количество спагетти-кода.
Как следует из названия, паттерн MVC разделяет ваше приложение на три уровня:
Модель хранит данные: Модель - это просто контейнер данных, в котором хранятся значения. Он не выполняет логику игрового процесса и не производит вычислений.
Вид - это интерфейс: View форматирует и выводит на экран графическое представление ваших данных.
Контроллер управляет логикой: Считайте, что это мозг. Он обрабатывает данные игры и вычисляет, как изменяются значения во время выполнения.
Такое разделение задач также определяет, как эти три части взаимодействуют друг с другом. Модель управляет данными приложения, а представление отображает эти данные для пользователя. Контроллер обрабатывает входные данные и выполняет любые решения или вычисления на основе игровых данных. Затем он отправляет результаты обратно в Модель.
Контроллер не содержит в себе никаких игровых данных. Не обошлось и без "Взгляда". Конструкция MVC ограничивает возможности каждого слоя. Одна часть хранит данные, другая обрабатывает их, а третья отображает их пользователю.
На первый взгляд, это можно считать продолжением принципа единоличной ответственности. Каждая часть выполняет одну задачу и делает это хорошо, что является ключевым преимуществом архитектуры MVC.
При разработке проекта Unity с помощью MVC существующий фреймворк пользовательского интерфейса (либо UI Toolkit, либо Unity UI) естественным образом выполняет функцию представления. Поскольку движок предоставляет вам полную реализацию пользовательского интерфейса, вам не придется разрабатывать отдельные компоненты пользовательского интерфейса с нуля.
Однако следование традиционному паттерну MVC потребовало бы, чтобы код, специфичный для представления, отслеживал любые изменения в данных модели во время выполнения.
Хотя такой подход вполне оправдан, многие разработчики Unity предпочитают использовать вариацию MVC, где контроллер выступает в качестве посредника. Здесь представление не наблюдает модель напрямую. Вместо этого он делает что-то вроде того, что показано на рисунке выше.
Эта вариация на тему MVC называется дизайном Model View Presenter, или MVP. MVP по-прежнему сохраняет разделение задач с помощью трех отдельных уровней приложений. Однако это несколько меняет обязанности каждой части.
В MVP презентер (в MVC он называется контроллером) выступает в роли промежуточного звена для других уровней. Он извлекает данные из модели и затем форматирует их для отображения в представлении. MVP переключает, какой уровень обрабатывает входные данные. За обработку пользовательского ввода отвечает не контроллер, а представление.
Обратите внимание на то, как события и шаблон наблюдателя вписываются в этот дизайн. Пользователь может взаимодействовать с компонентами Unity UI - кнопками, тумблерами и слайдерами. Слой представления отправляет эти данные ведущему с помощью событий пользовательского интерфейса, а тот, в свою очередь, манипулирует моделью. Событие изменения состояния модели сообщает ведущему, что данные были обновлены. Ведущий передает измененные данные в представление, которое обновляет пользовательский интерфейс.
На Github доступен пример проекта, демонстрирующий различные паттерны программирования, включая пример реализации вариации MVP.
Пример MVP состоит из простой системы, которая показывает здоровье персонажа или предмета. В этом примере все находится в одном классе, в котором смешаны данные и пользовательский интерфейс, но это не будет хорошо масштабироваться в реальном мире. Добавление дополнительных функций будет усложняться по мере расширения. Кроме того, тестирование и рефакторинг приведут к большим накладным расходам.
Вместо этого вы можете переписать компоненты здоровья более ориентированным на MVP способом, начав с разделения скриптов на Health и HealthPresenter.
В примере проекта можно щелчком мыши повредить целевой объект, представленный стреляющим диском(ClickDamage.cs), или сбросить здоровье с помощью кнопки. Эти события информируют HealthPresenter (который вызывает повреждение или сброс), а не изменяют здоровье напрямую. Текст пользовательского интерфейса и слайдер пользовательского интерфейса обновляются, когда Health поднимает событие и уведомляет HealthPresenter об изменении значений.
Давайте подробнее рассмотрим, как может выглядеть компонент Health. В этой версии в качестве модели выступает Здоровье. Он хранит фактическое значение здоровья и вызывает событие HealthChanged каждый раз, когда это значение меняется. Health не содержит игровой логики, только методы для инкремента и декремента данных.
Это позволяет четко разграничить данные, способ их представления и способ управления ими.
MVP (и MVC) действительно хорошо подходят для больших и тяжелых в плане пользовательского интерфейса программных приложений, но они не ограничиваются только этими вариантами использования. Если для разработки вашей игры требуется большая команда и вы рассчитываете поддерживать ее в течение длительного времени после запуска, вы можете воспользоваться следующими преимуществами:
Четкое разделение труда: Поскольку вы отделили представление от презентатора, разработка и обновление пользовательского интерфейса может происходить практически независимо от остальной части кодовой базы. Это позволяет разделить труд между специализированными разработчиками. В вашей команде есть опытные фронтенд-разработчики? Пусть они позаботятся о "Виде".
Упрощенное модульное тестирование с помощью MVP и MVC: Эти паттерны проектирования отделяют логику игрового процесса от пользовательского интерфейса. Таким образом, вы можете симулировать объекты для работы с кодом без необходимости входить в режим Play в редакторе. Это может сэкономить значительное количество времени.
Читаемый код, который можно поддерживать: При использовании этого шаблона проектирования вы будете стремиться создавать классы меньшего размера, что облегчает их чтение. Меньшее количество зависимостей обычно означает меньшее количество мест, где ваше программное обеспечение может сломаться, меньше мест, где могут быть скрыты ошибки, и более простое тестирование.
Хотя MVC и MVP широко распространены в веб-разработке или корпоративном программном обеспечении, зачастую их преимущества не очевидны до тех пор, пока ваше приложение не достигнет достаточного размера и сложности. Прежде чем внедрять любой из этих паттернов в свой проект Unity, вам необходимо учесть следующее:
Вам нужно все спланировать заранее: MVC и MVP - это более крупные архитектурные паттерны. Чтобы использовать один из них, вам придется разделить классы по ответственности, что требует определенной организации и дополнительной работы. Паттерны проектирования лучше всего использовать последовательно, поэтому вы должны выработать практику организации пользовательского интерфейса и убедиться, что ваша команда согласна с ней.
Не все в вашем проекте Unity будет соответствовать шаблону: В "чистой" реализации MVC или MVP все, что выводится на экран, действительно является частью представления. Не каждый компонент Unity легко разделить на данные, логику и интерфейс (например, MeshRenderer). Кроме того, простые скрипты могут не получить много преимуществ от MVC/MVP.
Вам нужно будет определить, где вы сможете извлечь наибольшую пользу из узора. Обычно вы можете позволить юнит-тестам направлять вас. Если MVC/MVP могут облегчить тестирование, рассмотрите их для этого аспекта приложения. В противном случае не пытайтесь навязать узор своему проекту.
Еще больше советов по использованию паттернов проектирования в приложениях Unity, а также принципов SOLID вы найдете в бесплатной электронной книге Повысьте уровень своего кода с помощью паттернов игрового программирования.
Если вы хотите получить более подробные инструкции по использованию Unity UI и UI Toolkit, обратитесь к обширному руководству, Проектирование и реализация пользовательского интерфейса в Unity руководство, написанное профессионалами в области пользовательского интерфейса.
Все передовые технические электронные книги и статьи по Unity можно найти в хабе лучших практик. Электронные книги также доступны на странице " Передовые методы" в документации.