Что общего между Telegram-ботами, турникетами и светофорами: конечные автоматы на практике

Представьте обычное утро в метро. Вы подходите к турникету, прикладываете карту, и... турникет решает, пропустить вас или нет. В этот момент происходит маленькое чудо автоматизации – турникет действует как конечный автомат, простая но эффективная система принятия решений.

В этой статье я хочу вам рассказать и показать на простом примере что это такое и как их можно применять в своих проектах. Больше интересных заметок о разработке и программировании читайте в моем Telegram-блоге «Код без тайн».

Алексей Иванов
Фулстек веб-разработчик

Конечные автоматы в повседневной жизни

Конечный автомат – это система, которая может находиться в одном из нескольких состояний и переходить между ними по определённым правилам. Звучит сложно? Давайте разберем на примере того же турникета.

У него есть два состояния: проход либо закрыт, либо открыт.

Каждое состояние четко определено на схеме автомата, и переходы между ними происходят по конкретным правилам – приложили карту, проверили баланс, открыли проход или показали ошибку. В случае турникета возможно всего два события — можно либо попытаться пройти через него (даже в случае, если он закрыт), а можно сначала оплатить. На схеме эти правила можно представить вот так:

Схема конечного автомата для турникета. Источник: <a href="https://api.vc.ru/v2.8/redirect?to=https%3A%2F%2Fcommons.wikimedia.org%2Fwiki%2FFile%3ATurnstile_state_machine_colored.svg&postId=1767177" rel="nofollow noreferrer noopener" target="_blank">Chetvorno</a>
Схема конечного автомата для турникета. Источник: Chetvorno

От турникетов к чат-ботам

Теперь давайте представим, что вместо турникета у нас Telegram-бот для записи к парикмахеру. Принцип тот же – бот находится в определенном состоянии и ждет действий пользователя. Например:

from enum import Enum class BotState(Enum): WAITING = "ожидание" CHOOSING_SERVICE = "выбор услуги" SELECTING_DATE = "выбор даты" CONFIRMING = "подтверждение" class HairdresserBot: def __init__(self): self.state = BotState.WAITING self.user_data = {} # Обработка вхоядщего сообщения def handle_message(self, message: str) -> str: if self.state == BotState.WAITING: return self.start_booking() elif self.state == BotState.CHOOSING_SERVICE: return self.handle_service_choice(message) # ... остальные состояния

В этом простом примере бот – это обычный конечный автомат с четырьмя состояниями. Каждое состояние определяет, как бот будет реагировать на сообщения пользователя.

Почему нельзя просто написать код?

Конечные автоматы – это не просто красивая теория. Они помогают:

  • Структурировать логику бота
  • Упростить отладку и тестирование
  • Легко добавлять новые функции
  • Контролировать пользовательский опыт

Благодаря такому подходу можно упростить реализацию сложной логики в боте, особенно когда нужно учитывать много переплетающихся между собой состояний и условий. Без использования конечного автомата в этом случае у вас получится спагетти из if-then-else:

def handle_message(message): if not user_data: if message == "/start": return "Привет! Выберите услугу" else: return "Используйте /start" elif user_data.get('service') is None: if message in services: user_data['service'] = message return "Выберите дату" else: return "Неверная услуга" elif user_data.get('date') is None: if is_valid_date(message): # и так далее...
Реализация сложной логики в вашем бота без конечных автоматов. <a href="https://api.vc.ru/v2.8/redirect?to=https%3A%2F%2Fdepositphotos.com%2Fphoto%2Fcolorful-tangled-threads-isolated-on-white-background-closeup-250881608.html&postId=1767177" rel="nofollow noreferrer noopener" target="_blank">Источник</a>
Реализация сложной логики в вашем бота без конечных автоматов. Источник

Как использовать конечные автоматы для разработки

Существует 3 варианта, как можно использовать такой подход при разработке своего бота:

1. Написать собственную маленькую реализацию конечного автомата

Этот подход рекомендуется, если вы сами занимаетесь программированием и хотите получить новый инструмент в свой арсенал. Много времени потратить не придется, потому что реализовать конечный автомат на самом деле легко — основное время вы потратите на изучение теории.

Зато в результате вы поймете как применять на практике мощную абстракцию, которая используется повсеместно: от интерфейсов на веб-сайтах, до микроволновки на вашей кухне.

2. Воспользоваться готовыми библиотеками

Такой вариант подходит, если вам нужно создавать и поддерживать много сценариев, реализованных на базе конечных автоматов.

Некоторые библиотеки, например, xstate, имеют графический редактор и инструменты для создания и моделирования автоматов отдельно от вашего кода. Это может быть удобно, если у вас несколько человек в команде и не все занимаются программированием.

Например, продакт-менеджер или другой член вашей команды может скорректировать сценарий, а вам как разработчику останется всего лишь обновить код.

3. Использовать no-code конструкторы

Все no-code конструкторы для создания ботов используют интерфейс, похожий на тот, который используется для создания конечных автоматов. На самом деле, если вы ранее создавали ботов в подобных конструкторах, то материал в данной статье может показаться вам знакомым.

Пример создания бота в no-code конструкторе. <a href="https://api.vc.ru/v2.8/redirect?to=https%3A%2F%2Fsoftfinder.ru%2Fservice%2Fpuzzlebot&postId=1767177" rel="nofollow noreferrer noopener" target="_blank">Источник</a>
Пример создания бота в no-code конструкторе. Источник

Дело в том, что принципы, которые используются в подобных конструкторах идентичные: вы создаете состояния (обычно это действия вроде отправки ответов или создания записи в таблице). Далее указываются триггеры для срабатывания состояний — какое состояние идет за каким и при каких условиях это событие срабатывает.

Подводя итог

Какой бы способ вы ни выбрали, на мой взгляд важно понимать то, как устроена изнутри система, которую вы разрабатываете. Даже если вы не являетесь программистом, важно понимать фундаментальные принципы, которые лежат в системах, которыми вы пользуетесь. Это дает большую свободу при взаимодействии с такими системами, а также повышает ваш уровень как специалиста.

Если вам понравилась эта статья, буду благодарен, если поставите лайк 🔥 и напишите комментарий — так я пойму, что на подобные темы стоит писать больше.

Также я веду свой Telegram-блог «Код без тайн», в котором пишу о веб-разработке, информатике и других технологиях:

6
1
1 комментарий

Когда-нибудь начну изучать python

1