FSM вместо if/else в backend — мой опыт
На производственной практике писал backend-систему управления проектами — и упёрся в проблему состояний 🤔
У проекта есть этапы: дизайн → разработка → QA → релиз → поддержка → архив И просто так прыгать между ними нельзя
Например: — нельзя начать разработку без утверждённой спецификации — некоторые переходы требуют причину — все изменения нужно фиксировать
Сначала хотел решать это через if/else… но быстро понял, что логика размажется по коду и станет неуправляемой
👉 В итоге реализовал конечный автомат (FSM) через библиотеку Stateless Вот пример перехода в домене: public ProjectTransitionResult StartDevelopment() { if (!HasApprovedSpecification()) return ProjectTransitionResult.Fail("No approved specification"); return Execute(ProjectTrigger.StartDevelopment); }
А внутри — единая точка управления переходами: if (!machine.CanFire(trigger)) return ProjectTransitionResult.Fail( $"Cannot execute {trigger} from {Stage}");
Теперь: — допустимые переходы описаны явно — бизнес-правила живут в домене, а не в контроллерах — каждый переход фиксируется в истории — ошибка перехода — это не баг, а контролируемый результат
📌 FSM встроил прямо в доменную модель (Clean Architecture) Параллельно применил: — Clean Architecture (Роберт Мартин) — CQRS + MediatR (Vertical Slice) — ASP.NET Core + PostgreSQL — JWT + роли
📚 Что повлияло на решения: — «Чистая архитектура» — Роберт Мартин — «Гид по Computer Science» — Уильям Спрингер — доклады с DotNext (идея использовать FSM вместо условий)
📂 Проект: https://github.com/markld-ui/RedRamkaPractice
Что понял: FSM сильно упрощает работу с бизнес-логикой — ты явно видишь все переходы и ограничения Но платишь за это более сложным входом и проектированием на старте.
Интересно, как вы обычно решаете такие задачи с состояниями в проектах?🤔