Skip to content

Latest commit

 

History

History
56 lines (43 loc) · 6.8 KB

ddd.md

File metadata and controls

56 lines (43 loc) · 6.8 KB

Инструменты DDD

Артем Малышев

  • Сложность бывает разная, мы должны уменьшать привнесенную сложность и увеличивать естественую, делать проект полезнее.
  • DDD - писать софт с том же стиле, в котором говорим с экспертами в предметной области, все подходы, наименования должны быть сохранены.
  • Это улучшает читаемость для нетехнических спецов
  • Говорить с экспертами от бизнеса на одном языке, в одном контексте.
  • Не технология, а философия
  • Как привнести? Освоить техническую часть.
  • Книга вышла лет 18 назад, но все попытки что-то писать в таком стиле - не понятно как ее применять
  • Как мыслить и писать в ддд, если ты программист.
  • Как лучше всего ддд привносить в проект, как структурировать. Models-driven architecture, на первое место ставим модель внешнего мира. SmartUI - место, где есть выбор технологи.й отсылка к чистой архитектуре по слоям.
  • Что такое модель? Это не UML. Это набор классов методов и референсов, который отражает бизнес-сценарии, происходящие в программе, высокоуровневую модель данных, по которой принимаются решения на основе бизнес-кейсов. Но методы и классы - низкоуровневые.

DRY Python. - библиотека для DDD

  • DRY Python - библиотеки для проектирования MDA.
  • Сервисы - это описание бизнес-процессов.
  • Библиотека stories - как писать бизнес истории и выносить в продукт. Описание процесса и состояние, реализация каждого шага бизнес-сценарий не смешивать, три разные вещи.
  • добавляем в джанго проект пакет services и постепенно переписываем на сценарии. позволяет писать спеки на DSL. Способ пошагово описать происходящее.
  • Опишем контракт, обозначим скоуп переменных и набор валидаторов. состояние процесса упадет на ошибке.
  • Пишем реализацию каждого шага. Метод соответствует бизнес-шагам, получает на вход состояние, напрямую модифицировать не может. Вернет маркер, например, успех, положи в скоуп переменные.
  • Story - объект, который работает как метод, делает трек происходящего в бизнес-процессе.
  • DEbug toolbar - посмотреть реквесты и состояния на каждый сценарий. Аналогично на Pytest.
  • Sentry: в breadcrumbs отчет о действиях пользователей.
  • ELK - пилится плагин для ElasticSearchKibana с индексами, можно будет искать. Без строчки кода логирования.

Что дальше

  • Смотрим, что за состояния внутри бизнес-процессов.
  • Entity, aggregate, value objects
  • корень агрегации для работы напрямую, как целостным объектом.
  • Делаем пустой пакет для агрегатов.
  • В контексте стори могут лежать только агрегаты.

Мапперы

  • Позволяет высокоуровневые абстракции маппить на то, как мы их храним
  • Добавляем repositories для хранения мапперов
  • Например, маппим дата класс на джанго модель ORM. Маппер будет сравнивать дата класс с моделью.
  • Можно написать кусочек сваггер схемы для микросервисов, анлогично для GraphQL queries, конкретный запрос graphql транслировать в структуры данных

А зачем это все?

  • Можно огрести из-за неконсистентности сервисов

  • DependencyInjection

  • Refactoring Roadmap - переписывание с джанго сигналов на ддд. Если проект уже перерос MVP, и вы задумались за архитектуру.

Вопросы

  • Если бизнес-кейс длинный и распределен на несколько сервисов и слоев, как быть? Можно писать длинную стори, контакт будет как единственный источник правды, но это будет тормозить. Можно как в подходе с celery, тогда будет н-мини сториз, который будут вызывать друг друга. Хочется видеть историю и контекст выполнения каждой стори - этот плагин в планах.
  • Как вы оцениваете оверхед за использование надстройки мапперов над репозиторием? Какой выигрыш по сравнению с автомапперами в алхеми. Не надо писать boilerplate, в реализации мы залезли "в кишки" каждого сервиса (django queryset, graphql etc) и встроили туда куски.
  • Интеграции с различными технологиями ии фреймворками. Если не джанга? Поддерживается дебаг тулбар, django, celery, flask.
  • Что делать с dependency injection, если ей требуется конфигурация. Поддерживает скоупы, в контейнере положить dict и в нем есть вложенные сеттинги (ps, redis), он может брать в соседнем классе настройки.