Без компромиссов
Сказав А, спешу сказать Б )
В предыдущем посте зафиксировал свою позицию:
"По возможности обходится без компромиссов"
Реально ли это?
Да, если не принимать на веру постулат о взаимозависимости качеств системы.
Качества системы безусловно связаны, но как ?
Если набросать граф зависимости качеств от групп тактик (примерно как на рисунке), то можно выработать стратегию движения в обход компромисса.
То есть вытянуть все хвосты, не жертвуя ни одним качеством (хотя вложится зачастую придётся).
Например, введение механизмов безопасности безусловно ухудшает производительность, но мы можем вытянуть производительность на нужный уровень за счёт оптимизации (эффективности).
И еще один трюк:
Если мы правильно проведем декомпозицию, то разные качества распределятся по разным модулям.
Например, если мы вытянем все, что связано с безопасностью в отдельный модуль, то оставшиеся качества надежность и производительность мы можем вытягивать масштабированием.
Сказав А, спешу сказать Б )
В предыдущем посте зафиксировал свою позицию:
"По возможности обходится без компромиссов"
Реально ли это?
Да, если не принимать на веру постулат о взаимозависимости качеств системы.
Качества системы безусловно связаны, но как ?
Если набросать граф зависимости качеств от групп тактик (примерно как на рисунке), то можно выработать стратегию движения в обход компромисса.
То есть вытянуть все хвосты, не жертвуя ни одним качеством (хотя вложится зачастую придётся).
Например, введение механизмов безопасности безусловно ухудшает производительность, но мы можем вытянуть производительность на нужный уровень за счёт оптимизации (эффективности).
И еще один трюк:
Если мы правильно проведем декомпозицию, то разные качества распределятся по разным модулям.
Например, если мы вытянем все, что связано с безопасностью в отдельный модуль, то оставшиеся качества надежность и производительность мы можем вытягивать масштабированием.
Архитектурный квант
Обратил внимание, что концепция архитектурного кванта не знакома многим архитекторам.
На мой взгляд это интересная модель, позволяющая быстро описать готовую архитектуру.
Нил Форд и ко. считают квантом элемент архитектуры, имеющий слабую статическую и динамическую связанность с другими элементами.
То есть, упрощая, это автономный модуль который можно
- независимо разрабатывать (статическая связанность),
- автономно запускать (динамическая связанность).
То есть, правильная микросервисная архитектура это много квантов, а распределенный монолит это один квант (хоть и много сервисов).
Кванты относятся к доменам отношением многое на многое.
- Можно все домены затолкать в один монолит.
- Можно, напротив, один домен расщепить на несколько квантов.
В итоге, объем кванта может быть существенно меньше ограниченного контекста диктуемого предметкой.
Могут существовать различные причины для тонкой декомпозиции.
Собственно и в самом DDD домен раскидывается на поддомены ради извлечения смыслового ядра. )
Обратил внимание, что концепция архитектурного кванта не знакома многим архитекторам.
На мой взгляд это интересная модель, позволяющая быстро описать готовую архитектуру.
Нил Форд и ко. считают квантом элемент архитектуры, имеющий слабую статическую и динамическую связанность с другими элементами.
То есть, упрощая, это автономный модуль который можно
- независимо разрабатывать (статическая связанность),
- автономно запускать (динамическая связанность).
То есть, правильная микросервисная архитектура это много квантов, а распределенный монолит это один квант (хоть и много сервисов).
Кванты относятся к доменам отношением многое на многое.
- Можно все домены затолкать в один монолит.
- Можно, напротив, один домен расщепить на несколько квантов.
В итоге, объем кванта может быть существенно меньше ограниченного контекста диктуемого предметкой.
Могут существовать различные причины для тонкой декомпозиции.
Собственно и в самом DDD домен раскидывается на поддомены ради извлечения смыслового ядра. )
Прямоугольники и стрелочки
Архитектурный квант Обратил внимание, что концепция архитектурного кванта не знакома многим архитекторам. На мой взгляд это интересная модель, позволяющая быстро описать готовую архитектуру. Нил Форд и ко. считают квантом элемент архитектуры, имеющий слабую…
Компоненты программной системы
Поздно подумал, что надо было проиллюстрировать предыдущий пост.
Ну лучше поздно, чем никогда.)
Поздно подумал, что надо было проиллюстрировать предыдущий пост.
Ну лучше поздно, чем никогда.)
Причины декомпозиции
«Вах, зачем ты предлагаешь мне декомпозицию? Как это снизит связанность? Связи останутся те же, только часть из них станет внешними. В итоге мы получим медленные, ненадежные взаимодействия» (из разговора с заказчиком).
1. Говоря о причинах декомпозиции, многие вспоминают связанность.
Связанность (англ. coupling, рунглиш. каплинг) — мера взаимосвязи элементов системы.
Мол, декомпозировать нужно для того, чтобы уменьшить связанность.
Отнюдь.
Так можно договориться до того, что повышать качество системы нужно ради хорошего коэффициента покрытия модульными тестами.
2. Причина декомпозиции в другом: необходимо подчинить себе сложность системы. Притом сложность сразу на нескольких этапах: сложность разработки, сложность выкатки, сложность сопровождения и т. д.
Верю, что когда кожаных специалистов заменит искусственный интеллект, не знающий сложностей, надобность в декомпозиции отпадёт.
3. Возьмём, к примеру, первичную декомпозицию системы. В редких случаях все ее части строятся на одной онтологии. Зачастую система распадается на множество элементов (доменов, предметных областей), описываемых различными языками. Заставьте разработчиков думать сразу на нескольких языках (Ubiquitous Language) и повторите судьбу строителей вавилонской башни.
Одним из паттернов первичной декомпозиции у Криса Ричардсона является декомпозиция по предметке
(см. https://microservices.io/patterns/decomposition/decompose-by-subdomain.html).
И где здесь про связанность?
4. Если уж говорить про метрики, то лучшей метрикой декомпозиции является сцепленность.
Сцепленность (англ. cohesion) — мера «близости» элементов системы.
Упрощая, мы можем проранжировать все связи по «правильности» и провести декомпозицию так, чтобы «правильные» связи попадали в общий элемент, а «неправильные» связывали элементы между собой.
Минимизировать количество и степень неправильных связей (снизить связанность) — это задача распределения ответственностей и дизайна взаимодействий, а не декомпозиции.
5. Список «правильных» и «неправильных» связей можно найти в стандарте ISO/IEC/IEEE 24765.
Однако этот список изначально был ориентирован на низкоуровневый дизайн и поэтому не полон.
Например, в этом списке есть сцепленность по общим данным, но нет сцепленности по общему языку, которую мы активно используем.
6. Хотелось бы хотя бы тезисно накидать алгоритм декомпозиции, указав, какие сцепки используются на разных уровнях иерархии системы.
«Вах, зачем ты предлагаешь мне декомпозицию? Как это снизит связанность? Связи останутся те же, только часть из них станет внешними. В итоге мы получим медленные, ненадежные взаимодействия» (из разговора с заказчиком).
1. Говоря о причинах декомпозиции, многие вспоминают связанность.
Связанность (англ. coupling, рунглиш. каплинг) — мера взаимосвязи элементов системы.
Мол, декомпозировать нужно для того, чтобы уменьшить связанность.
Отнюдь.
Так можно договориться до того, что повышать качество системы нужно ради хорошего коэффициента покрытия модульными тестами.
2. Причина декомпозиции в другом: необходимо подчинить себе сложность системы. Притом сложность сразу на нескольких этапах: сложность разработки, сложность выкатки, сложность сопровождения и т. д.
Верю, что когда кожаных специалистов заменит искусственный интеллект, не знающий сложностей, надобность в декомпозиции отпадёт.
3. Возьмём, к примеру, первичную декомпозицию системы. В редких случаях все ее части строятся на одной онтологии. Зачастую система распадается на множество элементов (доменов, предметных областей), описываемых различными языками. Заставьте разработчиков думать сразу на нескольких языках (Ubiquitous Language) и повторите судьбу строителей вавилонской башни.
Одним из паттернов первичной декомпозиции у Криса Ричардсона является декомпозиция по предметке
(см. https://microservices.io/patterns/decomposition/decompose-by-subdomain.html).
И где здесь про связанность?
4. Если уж говорить про метрики, то лучшей метрикой декомпозиции является сцепленность.
Сцепленность (англ. cohesion) — мера «близости» элементов системы.
Упрощая, мы можем проранжировать все связи по «правильности» и провести декомпозицию так, чтобы «правильные» связи попадали в общий элемент, а «неправильные» связывали элементы между собой.
Минимизировать количество и степень неправильных связей (снизить связанность) — это задача распределения ответственностей и дизайна взаимодействий, а не декомпозиции.
5. Список «правильных» и «неправильных» связей можно найти в стандарте ISO/IEC/IEEE 24765.
Однако этот список изначально был ориентирован на низкоуровневый дизайн и поэтому не полон.
Например, в этом списке есть сцепленность по общим данным, но нет сцепленности по общему языку, которую мы активно используем.
6. Хотелось бы хотя бы тезисно накидать алгоритм декомпозиции, указав, какие сцепки используются на разных уровнях иерархии системы.
Связанность и сцепленность
Если эта тема интересна, могу продемонстрировать на примере.
Если эта тема интересна, могу продемонстрировать на примере.
Anonymous Poll
87%
Интересно
3%
Не интересно
3%
И так всё понятно
7%
Не отвечу, но результат посмотрю😉
Прямоугольники и стрелочки
Причины декомпозиции Ну и запоздалая иллюстрация )
image_2024-10-07_00-15-17.png
28.8 KB
Уменьшение связанности
(«Правильный ответ»)
Понятно, что правильный ответ в архитектуре всегда зависит от условий конкретной задачи.
Но есть наборы тактик, позволяющих ослабить связанность, и это сужает область поисков.
У SEI таких тактик четыре (см. рисунок).
Правда, если внимательно вчитаться, то остается только две. )
Ограничение зависимости — это уточнение тактики «Посредник», посредник же — частный случай инкапсуляции.
Плюс абстрагирование, которое не уменьшает количество связей, а ослабляет их.
Оба решения были названы в комментариях.
Оркестратор — пример посредника.
Событийка на Publisher-Subscriber — пример повышения уровня абстракции.
ИМХО:
Я бы чуть расширил этот список.
Раз с помощью декомпозиции и перераспределения ответственностей можно увеличить связанность, то уменьшить ее можно с помощью объединения и того же перераспределения ответственности.
Чуть позже покажу это на примере.
Судя по голосованию — активно напросился. )
(«Правильный ответ»)
Понятно, что правильный ответ в архитектуре всегда зависит от условий конкретной задачи.
Но есть наборы тактик, позволяющих ослабить связанность, и это сужает область поисков.
У SEI таких тактик четыре (см. рисунок).
Правда, если внимательно вчитаться, то остается только две. )
Ограничение зависимости — это уточнение тактики «Посредник», посредник же — частный случай инкапсуляции.
Плюс абстрагирование, которое не уменьшает количество связей, а ослабляет их.
Оба решения были названы в комментариях.
Оркестратор — пример посредника.
Событийка на Publisher-Subscriber — пример повышения уровня абстракции.
ИМХО:
Я бы чуть расширил этот список.
Раз с помощью декомпозиции и перераспределения ответственностей можно увеличить связанность, то уменьшить ее можно с помощью объединения и того же перераспределения ответственности.
Чуть позже покажу это на примере.
Судя по голосованию — активно напросился. )
Event messages vs Command messages
1. Многие не видят принципиальной разницы между этими сообщениями.
Действительно ли сообщения-события связывают компоненты слабее, чем сообщения-команды?
2. Команды (Что сделать)
Проектировщики команд, а вслед за ними и проектируемый компонент «знают», кто и как будет обрабатывать команду. И явно декларируют предсказанное будущее в имени сообщения.
3. События (Что произошло)
Проектировщики событий лишены этого знания. События уходят на «другую сторону реки» и могут быть обработаны по-разному разными получателями, а могут и вообще потеряться.
Мы не можем явно описать их дальнейшую судьбу. Но мы все-таки должны дать им имя, полезное обработчикам. Даем имя по их прошлому, сообщая, как они родились.
4. Взаимозаменяемость
Можно ли использовать события вместо команд?
Да. Но мы теряем замечательную характеристику команды — ясность.
Можно ли использовать команды вместо событий?
Очевидно, нет. Не хватает знаний об их дальнейшей судьбе.
5. Подводя итог
У компонента, посылающего события, меньше знаний о связанных компонентах (эфферентная связанность).
Их связывает только общее знание структуры события. Но за это мы заплатили ясностью.(
1. Многие не видят принципиальной разницы между этими сообщениями.
Действительно ли сообщения-события связывают компоненты слабее, чем сообщения-команды?
2. Команды (Что сделать)
Проектировщики команд, а вслед за ними и проектируемый компонент «знают», кто и как будет обрабатывать команду. И явно декларируют предсказанное будущее в имени сообщения.
3. События (Что произошло)
Проектировщики событий лишены этого знания. События уходят на «другую сторону реки» и могут быть обработаны по-разному разными получателями, а могут и вообще потеряться.
Мы не можем явно описать их дальнейшую судьбу. Но мы все-таки должны дать им имя, полезное обработчикам. Даем имя по их прошлому, сообщая, как они родились.
4. Взаимозаменяемость
Можно ли использовать события вместо команд?
Да. Но мы теряем замечательную характеристику команды — ясность.
Можно ли использовать команды вместо событий?
Очевидно, нет. Не хватает знаний об их дальнейшей судьбе.
5. Подводя итог
У компонента, посылающего события, меньше знаний о связанных компонентах (эфферентная связанность).
Их связывает только общее знание структуры события. Но за это мы заплатили ясностью.(
Прямоугольники и стрелочки
Event messages vs Command messages 1. Многие не видят принципиальной разницы между этими сообщениями. Действительно ли сообщения-события связывают компоненты слабее, чем сообщения-команды? 2. Команды (Что сделать) Проектировщики команд, а вслед за ними и…
Event messages vs Command messages
(Иллюстрация)
В этот раз картинку не придумал, проиллюстрирую примером)
1. Предположим на подтверждение заказа вы запускаете процедуру доставки в другом сервисе.
2. Проще всего послать команду от сервиса заказов к сервису доставки (доставь_заказ(id)).
3. После выкатки релиза вас просят на подтверждение заказа добавить расчет бонусов.
4. Пишем еще одну команду к сервису бонусов, т. е. модифицируем сервис заказов
5. Предполагая, что появятся и другие задачи на подтверждение заказа, избавляемся от связанности
Вместо команды шлем событие (заказ_подтверждён(id)) в общую шину.
6.Теперь при любых добавлениях обработки сервис заказов не меняется.
Сервис заказов больше ничего не знает об обработчиках — низкая связанность.
7. При этом потеря знания — это и потеря ясности.
Разработчики сервиса заказов могут не знать, кто обрабатывает их событие, и наделать проблем.
Например, поменять структуру события, не предупредив всех заинтересованных лиц.
Сервис заказов больше не зависит от других компонентов, но другие компоненты все еще зависят от него.
8. Для возвращения ясности мы можем вернуть команды.
Однако, информация об этом в сервисе не сохранилась. Нужно проводить анализ. И не факт, что аналитики смогут отследить все варианты использования нашего события.
(Иллюстрация)
В этот раз картинку не придумал, проиллюстрирую примером)
1. Предположим на подтверждение заказа вы запускаете процедуру доставки в другом сервисе.
2. Проще всего послать команду от сервиса заказов к сервису доставки (доставь_заказ(id)).
3. После выкатки релиза вас просят на подтверждение заказа добавить расчет бонусов.
4. Пишем еще одну команду к сервису бонусов, т. е. модифицируем сервис заказов
5. Предполагая, что появятся и другие задачи на подтверждение заказа, избавляемся от связанности
Вместо команды шлем событие (заказ_подтверждён(id)) в общую шину.
6.Теперь при любых добавлениях обработки сервис заказов не меняется.
Сервис заказов больше ничего не знает об обработчиках — низкая связанность.
7. При этом потеря знания — это и потеря ясности.
Разработчики сервиса заказов могут не знать, кто обрабатывает их событие, и наделать проблем.
Например, поменять структуру события, не предупредив всех заинтересованных лиц.
Сервис заказов больше не зависит от других компонентов, но другие компоненты все еще зависят от него.
8. Для возвращения ясности мы можем вернуть команды.
Однако, информация об этом в сервисе не сохранилась. Нужно проводить анализ. И не факт, что аналитики смогут отследить все варианты использования нашего события.
Прямоугольники и стрелочки
Связанность и сцепленность
Если эта тема интересна, могу продемонстрировать на примере.
Если эта тема интересна, могу продемонстрировать на примере.
Завис на выборе задачи под пример декомпозиции (
- Задача должна быть более-менее знакомой (чтобы не зависнуть на этапе первого представления)
- Задача должна быть относительно простой (чтобы не разбирать ее неделями)
- Задача должна быть достаточно сложной (чтобы решение не было тривиальным, и включало как можно больше техник)
Есть идея взять что-нибудь очень хорошо всем знакомое, давно используемое.
То есть примерно так:
Как бы я спроектировал PowerPoint вернувшись на 25 лет назад.
Если есть интересные идеи - накидайте, пожалуйста. )
- Задача должна быть более-менее знакомой (чтобы не зависнуть на этапе первого представления)
- Задача должна быть относительно простой (чтобы не разбирать ее неделями)
- Задача должна быть достаточно сложной (чтобы решение не было тривиальным, и включало как можно больше техник)
Есть идея взять что-нибудь очень хорошо всем знакомое, давно используемое.
То есть примерно так:
Как бы я спроектировал PowerPoint вернувшись на 25 лет назад.
Если есть интересные идеи - накидайте, пожалуйста. )
KanDDDinsky2022-BalancingCoupling_public.pdf
26.3 MB
Презентация по одной хорошей книжке Влада Хононова (Vladikk).
Повозился немного с Яндекс GPT.
Vision системы за полчаса )
Vision системы за полчаса )
Прямоугольники и стрелочки via @telegraph
https://telegra.ph/Videne-sistemy-Slajdomet-10-14-2
Раскидал тему по верхнему уровню:
1. Контекст системы.
2. Концептуальная модель.
В конце концов готов к декомпозиции )
1. Контекст системы.
2. Концептуальная модель.
В конце концов готов к декомпозиции )
Странная ADR
Я видел достаточно много ADR, описывающих решения по проектированию системы.
Но мне очень редко попадались обоснования выбора того или иного архитектурного метода/подхода.
Архитекторы либо не желают рассказывать о своих методах, либо считают, что здесь никаких альтернатив не существует, и говорить, в сущности, не о чем.
Я решил не придерживаться общей традиции и начать декомпозицию с объяснений.
https://telegra.ph/ADR-2410201-10-20
Я видел достаточно много ADR, описывающих решения по проектированию системы.
Но мне очень редко попадались обоснования выбора того или иного архитектурного метода/подхода.
Архитекторы либо не желают рассказывать о своих методах, либо считают, что здесь никаких альтернатив не существует, и говорить, в сущности, не о чем.
Я решил не придерживаться общей традиции и начать декомпозицию с объяснений.
https://telegra.ph/ADR-2410201-10-20
Telegraph
ADR-2410201
Обоснование выбора метода структуризации системы «Слайдомёт». Контекст Необходимо выбрать подход к структуризации системы «Слайдомёт» с учетом следующих нюансов: - Крайне скудное описание системы. Анализ на этапе старта. Есть только виденье системы. - Предполагается…
Выбранный метод структуризации системы
(выжимка из лонгрида)
1. Структурируем транзакции, разбивая их по компонентам.
2. Проводим структуризации итерационно.
3. На каждой итерации определяем критерий сцепленности транзакций. Например, на первой итерации сцепленными будут транзакции, принадлежащие единому доменному языку.
4. Под сцепленные транзакции формируем компонент.
P.S. Если какая-нибудь вредная транзакция не захочет ложиться в наши компоненты, и мы ради нее не захотим менять структуру, то
разбиваем эту транзакцию на куски и делаем из нее сагу.
(выжимка из лонгрида)
1. Структурируем транзакции, разбивая их по компонентам.
2. Проводим структуризации итерационно.
3. На каждой итерации определяем критерий сцепленности транзакций. Например, на первой итерации сцепленными будут транзакции, принадлежащие единому доменному языку.
4. Под сцепленные транзакции формируем компонент.
P.S. Если какая-нибудь вредная транзакция не захочет ложиться в наши компоненты, и мы ради нее не захотим менять структуру, то
разбиваем эту транзакцию на куски и делаем из нее сагу.
ScyllaDB | Thank You
https://lp.scylladb.com/designing-data-intensive-apps-book-thanks
https://lp.scylladb.com/designing-data-intensive-apps-book-thanks
https://www.scylladb.com
ScyllaDB | Thank You
In this practical and comprehensive guide, Martin Kleppmann helps you navigate the diverse and fast-changing landscape of approaches to processing and storing data for data-intensive applications.
Клеппманн раздаёт бесплатно избранные главы из своей знаменитой книжки (с кабанчиком). Если еще не приобрели - рекомендую )
Декомпозиция системы "Слайдомёт" (1)
Давно обещанная декомпозиция.☺️
Не вся. Пара шагов первого этапа – сцепленность по языку.
https://telegra.ph/Strukturirovanie-sistemy-Slajdomyot-Pervaya-iteraciya-Vydelenie-kontekstov-10-28
Давно обещанная декомпозиция.
Не вся. Пара шагов первого этапа – сцепленность по языку.
https://telegra.ph/Strukturirovanie-sistemy-Slajdomyot-Pervaya-iteraciya-Vydelenie-kontekstov-10-28
Please open Telegram to view this post
VIEW IN TELEGRAM
Telegraph
Структурирование системы "Слайдомёт". Первая итерация – единый язык.
Цель итерации Построить высокоуровневую структуру системы "Слайдомёт" и зафиксировать её картой ограниченных контекстов.