Когда я разбираю чужую систему на аудите, первым делом задаю простой вопрос: почему у этого заказа такой статус? И очень часто никто не может ответить. Статус «отгружен», но отгрузки в системе нет. Оплата прошла, но счёт помечен как неоплаченный. Клиент в базе отмечен как «новый», хотя у него двадцать заказов. Данные есть, а причин у них нет. Система показывает следствия, которые ни из чего не следуют. Это самый верный признак того, что при проектировании кто-то забыл про причинно-следственную связь.
Бизнес-система это набор реакций на события
Любая учётная система, если снять с неё интерфейс, устроена очень просто. В мире что-то происходит: клиент оформил заказ, поставщик привёз товар, бухгалтер провёл оплату, менеджер отменил сделку. Это причины. Система на них реагирует: меняет остатки, создаёт документы, пересчитывает долги, отправляет уведомления. Это следствия. Всё. Вся сложность бизнес-логики сводится к тому, чтобы правильно описать, какое событие что вызывает и в каком порядке.
Я люблю сравнивать это с работой детектива. Хороший детектив не просто фиксирует, что в комнате разбита ваза. Он восстанавливает цепочку: кто вошёл, что задел, почему упало. Хорошая система должна уметь то же самое: для любого состояния данных ответить, какое событие к нему привело. Если не может, Вы управляете не бизнесом, а набором случайных цифр.
Где ломается причинность
За годы работы я составил для себя список типичных ошибок моделирования. Они встречаются в проектах любого размера, от маленьких магазинов до крупных учётных систем.
- Игнорирование промежуточных состояний. Заказ в модели бывает «новым» и «выполненным», а между ними пустота. В реальности же он проходит через резервирование, сборку, ожидание оплаты, передачу курьеру. Когда эти состояния не описаны, сотрудники начинают кодировать их комментариями, цветами строк и устными договорённостями.
- Нарушение последовательности операций. Деньги списались, а товар не зарезервировался, потому что между двумя действиями что-то упало. Система осталась в состоянии, которое не могло возникнуть ни из одной разумной цепочки событий.
- Прямое редактирование следствий. Кто-то вручную исправил остаток на складе, не проведя ни поступления, ни списания. Цифра стала «правильной», но причины у неё больше нет, и через месяц никто не поймёт, откуда она взялась.
- Смешивание бизнес-логики и интерфейса. Правило «при отмене заказа вернуть товар на склад» живёт в кнопке на экране. Отменили заказ через другой экран, через интеграцию или через мобильное приложение, и правило не сработало.
В хорошей модели нельзя изменить следствие, не создав причину. Это не бюрократия, это память компании о том, что с ней происходило.
Как строить модель, в которой всё объяснимо
Первое правило: проектируйте от событий, а не от экранов. Прежде чем рисовать формы, выпишите все события, которые происходят в Вашем бизнесе, на языке самого бизнеса: «клиент оформил заказ», «склад собрал отправление», «бухгалтерия подтвердила оплату». Для каждого события опишите, какие данные оно меняет. Экраны появятся потом, как способ инициировать эти события.
Второе: описывайте все состояния объекта и разрешённые переходы между ними. Из «новый» можно перейти в «зарезервирован» или «отменён», а из «отгружен» в «новый» нельзя. Это называется машина состояний, и она одна из самых полезных вещей в проектировании. Она сразу показывает дыры: а что будет, если клиент отменит заказ, который уже собран? А если оплата пришла после отмены?
Третье: связанные изменения проводите как единое целое. Списание денег и резервирование товара либо происходят вместе, либо не происходят вовсе. В технике это называют транзакцией, в жизни здравым смыслом. Половина операции хуже, чем отсутствие операции.
Четвёртое: храните историю событий. Не только текущий статус, но и то, кто, когда и по какой причине его изменил. Тогда на вопрос «почему у этого заказа такой статус» всегда будет ответ, а аудит превратится из археологии в чтение журнала.
Предсказуемость как главное качество
Правильная модель предсказуема. Глядя на событие, Вы точно знаете, к каким последствиям оно приведёт. Глядя на состояние, Вы точно знаете, какие события к нему привели. Это кажется скучным свойством, но именно оно позволяет системе расти. В непредсказуемую систему страшно добавлять новые функции, потому что никто не знает, что ещё сломается. В предсказуемую систему новые события добавляются спокойно, как новые ходы в игре с понятными правилами.
Мне в этом смысле близка физика: мир сложен, но он подчиняется законам, и именно поэтому его можно изучать и предсказывать. Бизнес-система должна быть маленькой вселенной со своими законами, а не набором чудес, которые иногда случаются с данными.
Что делать завтра
Возьмите один ключевой объект Вашего бизнеса, например заказ, и вместе с людьми, которые с ним работают, нарисуйте на доске все его состояния и стрелки переходов между ними. Подпишите каждую стрелку событием, которое её вызывает. Вы почти наверняка найдёте состояния, которые есть в жизни, но нет в системе, и переходы, которые система позволяет, а жизнь нет.
Мы в Ingello делаем это на каждом проекте: в Systems с этого начинается проектирование, а в Fractal карта экранов и сценариев описывается отдельным языком, так что цепочки причин и следствий видны ещё до того, как написана первая строка кода. Модель, в которой у каждого следствия есть причина, это не перфекционизм архитектора. Это способ сделать так, чтобы Ваша система всегда могла объяснить сама себя.