Конечный автомат — это некоторая абстрактная модель, содержащая конечное число состояний чего-либо. Используется для представления и управления потоком выполнения каких-либо команд. Если более простыми словами, это модель вычислений, основанная на гипотетической машине состояний. В один момент времени только одно состояние может быть активным. Следовательно, для выполнения каких-либо действий машина должна менять свое состояние. Конечный автомат идеально подходит для реализации искусственного интеллекта в играх, получая аккуратное решение без написания громоздкого и сложного кода
Конечные автоматы обычно используются для организации и представления потока выполнения чего-либо. Это особенно полезно при реализации ИИ в играх. Например, для написания «мозга» врага: каждое состояние представляет собой какое-то действие (напасть, уклониться и т. д.).
Как поможет конечный автомат в реальных проектах? Возьмём пример из реального проекта: Есть сценарий регистрации новых пользователей в системе. В процессе регистрации пользователь проходит через несколько этапов:
- заполнение анкеты;
- подтверждение электронной почты;
- привязка мобильного устройства через QR-код;
- окончание регистрации.
Представим, что мы занимаемся реализацией метода, устанавливающего состояние объекта Пользователь. Данный метод должен каждый раз проверять текущее состояние и корректность перехода в новое состояние согласно всем бизнес-правилам. Нельзя, например, привязать мобильный телефон, пока электронная почта не подтверждена. Или же нельзя дважды подтверждать один и тот же адрес электронной почты. Для реализации этого метода можно воспользоваться оператором switch:
Можно заметить, что такое решение имеет ряд недостатков:
- Если бизнес-правила изменятся, то в метод каждый раз придется вносить изменения.
- Этот код плохо читается, его неудобно сопровождать.
- Со временем подобные условия расползаются по коду, что приводит к ошибкам. Для решения данных проблем воспользуемся концепцией конечных автоматов. Мы рассмотрим реализацию на примере PHP, фреймворка Symfony и бандла StateMachineBundle. Существует целый ряд бандлов с реализацией конечных автоматов для Symfony, которые мы рассмотрим чуть позже. Допустим, на примере интернет-магазина. Одним из ключевых сценариев для интернет-магазина является процесс оформления заказа пользователем. Прежде чем заказ будет обработан, пользователь должен указать свои контактные данные, выбрать способ доставки и оплаты, при этом каждый этап может влиять на конечную стоимость заказа. Этот процесс можно представить в виде многоступенчатой формы. Важный момент: на любом этапе оформления можно вернуться к предыдущему шагу, что в свою очередь повлечет за собой изменение окончательной суммы заказа.
Наш конечный автомат имеет 5 возможных состояний (states) и 4 возможных перехода (transitions). Каждый переход регламентируется списком возможных исходных состояний (from) и целевым состоянием (to). Преимущества данного подхода очевидны:
- Простота и наглядность схемы, код понятен и не требует дополнительных комментариев.
- Возможность легко и быстро вносить изменения.
- Подходит для решения очень сложных задач.
Конечные автоматы — очень надежный и полезный инструмент для организации логики приложений, данный подход позволяет писать простой и понятный код.