Спасибо за такой развернутый комментарий. На самом деле вы подняли уровень обсуждения сильно выше того, что я рассматривал в серии. Я специально почти не затрагивал архитектуру бизнес-процессов, оркестрацию, транзакционность, идемпотентность, retry policy, компенсации, long-running операции, оптимизацию, восстановление состояния и т.д. Потому что хотел сначала изолированно показать более базовую проблему: как ведут себя зависимости внутри кода и почему одни архитектуры имеют тенденцию к росту связности и размыванию границ, а другие структурно ограничивают этот процесс. То есть серия была скорее про структурную деградацию системы, а не про деградацию бизнес-процессов.
По поводу примера с IUserServiceExternal тоже хороший момент. Но тут есть важная оговорка: серия писалась вокруг NestJS и TypeScript, а у них немного другие ограничения и возможности по сравнению с C#. В C# есть partial class и можно работать через интерфейсы, композицию, по другому организовывать DI и сборку сервисов. Поэтому конкретная реализация вполне может отличаться в зависимости от возможностей языка и фреймворка.
Для меня тут важнее был не сам формат handler vs service, а сохранение направленности зависимостей и DAG-структуры системы. То есть чтобы при росте проекта граф зависимостей оставался ацикличным и не начинал постепенно размывать границы модулей.
И отдельно спасибо за пример с заказами. Он очень показательный, потому что там сложность уже начинает жить не в зависимостях модулей, а в эволюции самих бизнес-процессов, оркестрации и обеспечении повторяемости сложных сценариев.
Спасибо за интерес! Все пять частей уже доступны часть 2 по ссылке, дальше из неё. В двух словах: 2-3 про то, как декомпозиция и forwardRef оборачиваются убытками в деньгах, 4 про подход, который снимает проблему, 5 формальное обоснование на теории графов.
Благодарю за развёрнутый отклик. Я опубликовал остальные части, агрегацию из нескольких доменов в части 4: если коротко, каждый модуль публикует наружу не «весь свой Service», а отдельный external/-порт; use-case, склеивающий данные из двух доменов, живёт в третьем модуле и импортирует только external’ы соседей — граф остаётся DAG’ом. Формальное обоснование, почему это держит форму на дистанции, — в части 5.
молодцы, парни. Надо девопсов жестко проверять, а то как-то ко мне один пришел, заявил, что он SRE даже, а не девопс, а сам месяц не мог поднять обычный кубер с ингресом
Information
Rating
425-th
Registered
Activity
Specialization
Бэкенд разработчик, Архитектор программного обеспечения
Спасибо за такой развернутый комментарий. На самом деле вы подняли уровень обсуждения сильно выше того, что я рассматривал в серии. Я специально почти не затрагивал архитектуру бизнес-процессов, оркестрацию, транзакционность, идемпотентность, retry policy, компенсации, long-running операции, оптимизацию, восстановление состояния и т.д. Потому что хотел сначала изолированно показать более базовую проблему: как ведут себя зависимости внутри кода и почему одни архитектуры имеют тенденцию к росту связности и размыванию границ, а другие структурно ограничивают этот процесс. То есть серия была скорее про структурную деградацию системы, а не про деградацию бизнес-процессов.
По поводу примера с
IUserServiceExternalтоже хороший момент. Но тут есть важная оговорка: серия писалась вокруг NestJS и TypeScript, а у них немного другие ограничения и возможности по сравнению с C#. В C# естьpartial classи можно работать через интерфейсы, композицию, по другому организовывать DI и сборку сервисов. Поэтому конкретная реализация вполне может отличаться в зависимости от возможностей языка и фреймворка.Для меня тут важнее был не сам формат
handler vs service, а сохранение направленности зависимостей и DAG-структуры системы. То есть чтобы при росте проекта граф зависимостей оставался ацикличным и не начинал постепенно размывать границы модулей.И отдельно спасибо за пример с заказами. Он очень показательный, потому что там сложность уже начинает жить не в зависимостях модулей, а в эволюции самих бизнес-процессов, оркестрации и обеспечении повторяемости сложных сценариев.
Спасибо! Согласен, по объёму статья не пятничная. Если на свежую голову прилетят мысли из опыта буду рад услышать)
Спасибо за интерес! Все пять частей уже доступны часть 2 по ссылке, дальше из неё. В двух словах: 2-3 про то, как декомпозиция и
forwardRefоборачиваются убытками в деньгах, 4 про подход, который снимает проблему, 5 формальное обоснование на теории графов.Благодарю за развёрнутый отклик. Я опубликовал остальные части, агрегацию из нескольких доменов в части 4: если коротко, каждый модуль публикует наружу не «весь свой Service», а отдельный external/-порт; use-case, склеивающий данные из двух доменов, живёт в третьем модуле и импортирует только external’ы соседей — граф остаётся DAG’ом. Формальное обоснование, почему это держит форму на дистанции, — в части 5.
молодцы, парни. Надо девопсов жестко проверять, а то как-то ко мне один пришел, заявил, что он SRE даже, а не девопс, а сам месяц не мог поднять обычный кубер с ингресом