Transactional Script: основа бизнес-логики
Сегодня мы рассмотрим паттерн Transactional Script — пожалуй, самый популярный и наиболее старый подход к организации бизнес-логики в приложениях. В простых сценариях и контекстах Domain Driven Design именно он будет часто и широко использоваться.
Этот паттерн был впервые формально описан Мартином Фаулером в его книге Patterns of Enterprise Application Architecture (2002), хотя самим подходом разработчики пользуются столько же, сколько существует программирование. Фаулер каталогизировал его как один из основных способов организации логики в корпоративных приложениях.
Суть паттерна предельно проста: каждый бизнес-сценарий выполняется в одной функции, которая получает входные данные, обрабатывает их, сохраняет результат и возвращает ответ. Но за этой простотой часто скрывается множество подводных камней, которые превращают ваш простой скрипт в сложный ком спагетти.
Давайте разберем все по порядку.
Как правильно писать transactional script
Давайте посмотрим, как организовать Transactional Script на «классическом» примере оформления заказа в интернет-магазине:
Ключевой принцип:
Вся бизнес-логика должна быть явно видна в одной функции — «скрипте» транзакции.
Можно выносить:
- валидацию,
- маппинг в DTO,
- обработку ошибок,
- технические детали (сохранение, публикация событий).
Но не стоит прятать саму суть операции — расчёт цены или применение скидки, в другие классы или методы без явной причины. Иначе логика «размазывается» и понять, что происходит становится сложно.
Ошибки при реализации Transactional Script
Очень частая ошибка — пытаться сделать красиво. Вспоминаем все практики из Clean Code и начинаем разбивать логику, чтобы код соответствовал всем принципам ООП — SOLID, DRY, SLAP и т. п. В результате бизнес-логика начинает размазываться по куче классов, и нам придется потратить много времени, чтобы разобраться.
Вот один из таких примеров:
Такой код выглядит чистым, но скрывает и размазывает бизнес-логику по куче классов.
Еще один пример, который часто встречается во множестве проектов:
Здесь важная бизнес-логика скрыта в фабрике, которая создает заказ. Мы не видим, как считается цена, применяется ли скидка и проверяются ли остатки.
Transactional Script — это не про «чистоту», а про прозрачность бизнес-процесса.
Когда использовать transactional script
Transactional Script — идеальный выбор в следующих ситуациях:
✔ Простые CRUD-операции, где логика — это валидация и сохранение.
✔ Операции с четкой последовательностью действий, не требующие сложных инвариантов.
✔ Отчеты и аналитика — собрать данные и выдать результат.
✔ В рамках DDD — для простых ограниченных контекстов (Bounded Contexts), где сложность домена простая.
✔ На начальных этапах проекта, когда еще не разобрались в доменной области.
В контексте DDD важно понимать: использование Transactional Script — это нормально.
DDD не требует повсеместного применения Domain Model. Он требует осознанного выбора инструмента под задачу.
Если контекст прост — используйте простой инструмент.
Мой канал в telegram