Why
Проблемы в разработке, показанные по шагам.
Разборов с такими тегами нет.
Зачем нужен Lean
Две акции сошлись на одном товаре и продали его дешевле закупки. Каждую согласовали и проверили по отдельности. Их сочетание не проверял никто.
Why DDD: bounded context
Каждый сервис устроен по-своему: своя раскладка каталогов, путаница в терминах, переизобретение велосипеда и наступление на одни и те же грабли в сотый раз. Знание про один сервис не переносится на следующий — ни у автора, ни на ревью, ни у того, кто придёт через год.
Why DDD: domain
Домен назвали словами, а в коде он остался структурой с открытыми полями и `float64` в деньгах. Правила предметной области живут у вызывающих: каждый держит свою половину, и однажды одна из них устаревает.
Why DDD: domain services
Правило пени считается по сроку, ставке и календарю рабочих дней. В агрегат оно не влезает — счёт начнёт знать про календарь; в сценарий его тоже нельзя — правило уедет из домена, и второй вызов посчитает иначе.
Why DDD: specification
Правило «счёт просрочен» живёт в трёх местах и нигде не названо: условие в `WHERE` у планировщика, поле в проекции чтения и отчёт для бухгалтерии. Первое же изменение правила поедет только в одно из трёх.
Why DDD: applications && infrastructure
Сценарий, база и входящий вызов расползаются по слоям, и кто из них что знает о домене — выясняется в проде: где началась транзакция, кто отправил факт и почему подписчик узнал о том, чего в базе нет.
Why DDD: transport && wiring
Сценарии написаны, порты закрыты реализациями — а позвать сервис нельзя: снаружи приходит JSON, а сценарий ждёт доменные сущности. И собрать это в работающий процесс тоже некому: `cmd/` пуст.
Why CQRS
Сценарий принимает пять параметров, и перепутать их в вызове ничто не мешает. Чтение при этом идёт через тот же агрегат: чтобы показать одну строку на экране, сервис собирает счёт целиком со всеми правилами, которые чтению не нужны.
Why aggregate versioning
Два вызова прочитали один счёт, оба применили своё правило, оба сохранили. В базе осталось изменение того, кто записал вторым — первое исчезло, и ни одна транзакция об этом не узнала: оба `UPDATE` прошли успешно.
Why integration events
Доменный факт уехал на шину как есть, со своими полями и типами. Сосед разобрал его и построился на нём: теперь переименование поля внутри домена ломает чужой сервис, и узнаём мы об этом из его алертов.
Закон Литтла
Интенсивность входного потока и время пребывания заявки есть в любом мониторинге. Третья величина — сколько заявок находится в системе — получается из этих двух умножением, но её обычно оценивают отдельно и приблизительно. Отсюда пулы, рассчитанные по числу пользователей, и пороги на глубину очереди, которые ничего не говорят о времени ожидания.
Системный дизайн: сервис скрейпинг-джоб
Задачу на системный дизайн дают абзацем текста без единого числа, и схему начинают рисовать с первой минуты. Потом выясняется, что у сервиса нет ни требований, ни оценок, и спорить про очередь не на чем: неизвестно, какую нагрузку она должна выдержать.