🚀
Реактивное программирование 🚀
Уровень материала: 🐥 #middle
О реактивном программировании довольно часто упоминается, особенно в чрезмерно динамичном геймдеве. Подход очень легко начать использовать, и на первый взгляд он может показаться очень понятным. Поэтому многие новички любят брать его на вооружение и «
прокачивать» свой код повсеместно. Но всё не так просто.
Я встретил хорошее видео, которое доступно поясняет устройство этой технологии. И подготовил несколько тезисов по теме.
📺
YouTube / 📝
Dzen📌 🔤🔤🔤 🔤🔤🔤🔤🔤 🔤🔤
🔤Реактивное программирование — это парадигма, где код строится вокруг
потоков данных* и их изменений. Вместо ручного обновления состояний мы подписываемся на события (
например, нажатие кнопки, изменение здоровья персонажа) и реагируем на них.
* речь про data streams, не путать с thread из многопоточностиКлючевое отличие от обычных событий — это то, что здесь данные образуют поток (
Observable), с которым можно взаимодействовать. Например, объединить несколько источников событий и реагировать не на все их события, а только, скажем, на первые
N чётных событий, где есть данные
X.
🔥 🔤🔤🔤🔤🔤
:1️⃣
Декларативность: Поток данных позволяет использовать цепочки операторов, которые помогают организовывать логику декларативно (
например, через LINQ).
2️⃣
Отписки: Все локальные подписки на поток агрегируются в
IDisposable-сущность. Соответственно для отписки нужно всего лишь вызвать
Dispose и не хранить делегаты, которыми производилась подписка, чтобы ими же потом отписаться.
3️⃣
Удобство: Библиотеки имеют много вспомогательных методов и специальных оберток для данных, которые позволяют быстро добавить возможность подписки на изменения.
⚠️ 🔤🔤🔤🔤🔤🔤
:1️⃣
Оверкилл: Избыточное решение для простых единичных событий или асинхронных операций, с которыми нет необходимости работать как с потоком данных.
2️⃣
Отладка: Цепочки операторов и иерархию подписок сложно дебажить.
3️⃣
Производительность: Зависит от применяемого решения, но Rx имеет свои накладные расходы, пусть и не всегда значительные.
4️⃣
Сериализация: Реактивные обёртки для данных могут доставлять неудобства при сериализации данных и передаче по сети.
🛠 🔤🔤🔤🔤🔤🔤🔤 🔤 🔤🔤🔤🔤🔤
:В Unity долгое время использовался пакет
UniRx, но теперь его активно замещает
R3 от тех же авторов, которые подарили нам и
UniTask.
Особенности последнего:➖ Не ограничивается Unity и поддерживает другие движки.
➖ Улучшенная производительность и меньше аллокаций.
➖ Поддержка «
покадровых» операций в игровых движках.
➖ Полноценная поддержка
async/await операций «
из коробки».
➖ Улучшен контроль за утечками памяти.
🧑💻 🔤🔤 🔤🔤🔤🔤
:В «
юные годы» меня сильно привлекла декларативность, которую даёт Rx. Но, пережив несколько игровых проектов на этой технологии и попробовав разнообразные сценарии, все обозначенные минусы сильно перевесили плюсы. Поэтому вывод, к которому я пришёл, — этого должно быть так же в меру, как и всего остального.
Rx, как, например, не менее популярный
Zenject (
именно он, не DI в целом), дают слишком широкий простор возможностей и сценариев использования. Это в будущем создаёт разнообразные проблемы и сложности, разрешить которые может оказаться намного сложнее, чем не поддаваться искушению изначально.
Я бы рекомендовал сначала обкатать технологию на пет-проектах всеми возможными способами, прощупать свои личные границы удобства и изучить долгосрочные последствия принятых решений.
А вне «
песочницы»: если нормально живётся без Rx — скорее всего, он не нужен. Rx — это, в первую очередь, про
потоки данных. Где работа с такими потоками не нужна, запрягать Rx и нет необходимости.
🔧 🔤🔤🔤🔤🔤🔤 🔤🔤🔤🔤🔤
:➖ Необходимость объединения и/или фильтрации событий от разных источников.
➖ Сложная обработка событий.
➖ Обработка ввода от игрока.
➖ Связь визуального слоя с игровыми данными.
➖ Контроль событий, распределённых во времени (
таймеры, задержки и пр.).
————————————
#unity #gamedev #development #architecture #rx #геймдев #разработка #архитектура #реактивность #рекомендация #видео