S0ER – Telegram
10.6K subscribers
333 photos
18 videos
15 files
707 links
Архитектура | Программирование | Профессиональное развитие

Соер.Клуб - https://news.1rj.ru/str/soer_live

По всем вопросам писать на @soerdev
Download Telegram
С DDD есть несколько нюансов, которые нужно помнить:
- DDD плохо ложится на Data Centric подход, т.е. если у вас простой CRUD+Rest вокруг него, то DDD скорее всего не нужен
- DDD не имеет смысла внедрять в маленьких приложениях, на самом деле если у вас порядка 30-40 User Stories, то это очень маленькое приложение, если начать делать его по DDD, то будет получен оверхед в виде ненужных Aggregate, Registry и Entities, куда проще использовать классический Transaction Script и сервисы.
По поводу анемичных моделей надо помнить, что у нас есть совершенно разные "логики":
- бизнес-логика, независимая от приложения
- бизнес-логика, возникающая в следствие автоматизации (по сути создания приложения)
- логика приложения (по сути обязанность приложения обеспечивать свою работу)
- обязанность получения и доступа к данным (логика работы с данными)

Анемичная модель возникает в случае когда бизнес-логика в рамках домена утекает из доменной модели в другую часть программы. Но анемичная модель не может, возникать вне рамок домена.
В чем причина разделения бизнес-логики и логики приложения в DDD?
Все дело в том, что бизнес-логика - это логика "реального" мира, на нее имеют влияние процессы, которые происходят за пределами "программы", поэтому причины и вектор развития бизнес-логики будут завязаны на "реальный мир", логика приложения же завязана исключительно на само приложение и изменение, и развитие будут происходить исключительно по внутренним причинам.

Так как темпы изменений и причины разные, то разделив логику приложения и бизнес-логику мы получим более гибкое решение, которое легче сопровождать и развивать.

Если же бизнес-логика и есть логика приложения (вырожденные случаи, когда мы разрабатываем приложение без бизнеса), то разделять их не имеет смысла.
Спасибо Хауди Хо за наводку про комментарии для постов, подключил чат для обсуждений, теперь должна появиться возможность комментировать оставленные сообщения.
В книге "Fundamentals of Software Architecture: An Engineering" Neal Ford, Mark Richards сформулирован офигенный "закон" архитектурного взгляда на проект, он звучит так: "'Why' is more important than 'how'"
Эта мысль мне нравится тем, что для понимания того как лучше реализовать ту или иную часть проекта, нужно последовательно понять следующие моменты:
- какие преимущества/недостатки есть в различных вариантах решения;
- какие ограничения есть в проекте;
- для чего мы реализуем тот или иной функционал.

Рассматривать поставленные вопросы нужно снизу вверх, тем самым мы как раз и приходим к простому закону: "'Why' is more important then 'how'".
Небольшая инфографика по вариантам архитектурных решений монолитных приложений
Есть мнение, что монолит - это реализация какого-то конкретного архитектурного стиля, некоторые даже считают, что это самостоятельный архитектурный стиль.
На самом деле монолит - это характеристика архитектуры рассматривающая возможность раздельного развертывания и характеризующая силу зацепления между компонентами архитектуры.
Монолитные приложения могут быть созданы с использованием разных архитектурных стилей, как на рисунке выше.
Основная особенность, все же, в монолите почти всегда "Data centric" подход с единственной БД и единственной связью между БД и приложением.
Тут нужно отметить, что с архитектурной точки зрения "единственная БД" - это не совсем техническая реализация, т.е. СУБД у вас может быть несколько, они могут быть как SQL так и NOSQL и т.д. Архитектурное представление на высоком уровне не отражает физическую реализацию, а определяет назначение компонента, его обязанности, и связи.
Обдумываю в каких ситуациях можно и нужно прибегать к параллельным вычислениям, вот такой список причин получился:
- легко формулируются как параллельные таски - задача очевидным образом разбивается на типовые подзадачи, независимые друг от друга;
- тяжелая математика - очевидно, что лучше считать параллельно от основных задач;
- задача сводится к Map-Reduce - это доп. условие к первому пункту, тут понятно, что надо map-reduce-ом решать;
- обработка графики - очевидно, что это опять же компиляция 1-2 пункта, но по сути это целый класс хорошо изученных задач, поэтому хорошо бы их сформулировать отдельно.

Какие еще причины/случаи/задачи вам приходят в голову?
Паттерн SAGA
SAGA - один из первых шаблонов для реализации транзакционной логики в распределенных системах. Он появился раньше чем микросервисная архитектура, но особую популярность приобрел вместе с микросервисами.

Идея шаблона сводится к идеи "целостность в конечном итоге", он состоит из цепочки нод, которые имеют свое состояние и работают по транзакционной модели ACID, каждая из нод либо выполняет транзакцию, либо инициирует цепочку отмены транзакции.

Взаимосвязь нод строится на базе событий, которые могут распространяться как синхронно, так и асинхронно.
Существует несколько вариантов реализации паттерна на практике, все зависит от конечных свойств, которые нужно получить в решении:

Атомарность vs Модульность
Синхронность vs Асинхронность
Оркестрация vs Хореография
Вариант атомарного, синхронного, оркестрированного поведения:
- существует одна большая распределенная транзакция (пунктир на рисунке)
- запросы получает медиатор, который принимает решение о том как исполнять запрос внутри транзакции
- ошибки обрабатывает так же медиатор, выполняя "откат транзакции" на уровне каждой ноды
- все запросы синхронные (например, http) и по результату запросу сразу приходит статус (медиатор ждет результата обработки)
пожалуй, самый простой из всех вариантов реализации SAGA
Сегодня выпустил стрим для патронов на тему SAGA, слайды тут - https://s0er.ru/codelabs/arch_stream_18
Вопрос: в чем разница между модульностью и грануляцией?
Ответ:
- модульность - это набор требований позволяющих провести разделение системы на составные части, часто слабо зацепленные друг на друга
- грануляция - это набор требований позволяющий найти оптимальный размер составных частей, без потери функциональности

грубо говоря модульность - про то как разделить на части, грануляция - про то как не делать сильно большие или сильно мелкие компоненты.


Чтобы понять когда менять грануляцию системы, нужно учесть следующие моменты по мере уменьшения важности и влияния на грануляцию:
- функциональность (исходим из бизнес-задач при объединении или разделении)
- домен изменений (если код неустойчив к изменениям и требует слишком много правок в разных частях, то пытаемся сгранулировать правильно)
- масштабирование и производительность (адаптируем размер компонент под задачи масштабирования)
- устойчивость к сбоям (стоит задуматься в случае если гранулирование может поменять эту характеристику в лучшую сторону)
- безопасность (точно так же как и устойчивость к сбоям, иногда грануляция помогает решить проблемы требований по безопасности, тогда имеет смысл провести новые границы)
👍2