Информация об изменениях

Сообщение Re[7]: Запутался с DDD от 21.10.2021 8:30

Изменено 21.10.2021 8:40 gandjustas

опечатка

Re[7]: Запутался с DDD
Здравствуйте, vaa, Вы писали:

vaa>Здравствуйте, gandjustas, Вы писали:


vaa>>>Очень много нюансов которые сложно обойти чтобы сделать невозможным не валидным состояние агрегата.

G>>Валидность состояния может также завесить от операции. Например нельзя отправить заказ клиенту с некорректным shipping address, но при этом вполне можно принять оплату при заполненном billing address. Такие правила в рамках системы типов выразить невозможно.

G>>Вот серия статей про моделирование предметной области с помощью типов (когда-нибудь я сделаю перевод, потому что статьи прекрасны)

G>>https://ericlippert.com/2015/05/11/wizards-and-warriors-part-five/
vaa>Интересно, в заключении автор изобрел функциональное программирование.
Чем оно функциональное? Ни ФВП, ни АТД, ни иммутабельности нет.

vaa>Не понятно почему он боится исключений. Это такой же способ управлять потоком программы как и if|else.

Исключение это не type safety, из-за которой собственно пытаются городить иерархии классов в стиле DDD. Если ты все сводишь к if-else и исключениям, то тебе не нужны кучи классов.
Об этом и речь в статье.

vaa>К тому же в его коде все время фигурирует void (в этом кстати косяк сеттеров в C# — они void, так что здесь без исключений уже никуда).

И что? Можно код значительно улучшить, не используя void?

vaa>Достаточно из каждого метода изменяющего состояние ввести возврат https://docs.microsoft.com/ru-ru/dotnet/fsharp/language-reference/results

Увы без pattern-matching такой подход не работает. Посмотри на дату статьи.

И еще раз повторю: смысл всех DDD-паттернов — вылазить правила и ограничения предметной области в виде классов для compile-time проверки корректности.
Все что уносит нас в рантайм-проверку требует другой архитектуры. Result = Some(x)|None это тоже рантайм проверка.

Липперт в своей статье описал эту архитектуру:

The classic paradigm for OOP still makes perfect sense: encode the fundamental, unchanging relationships between business elements into the type system. Here the fundamental unchanging relationships are things like “commands are evaluated in the context of state and rules, to produce a sequence of actions”, so that’s where the design should have started in the first place.


Перевожу:

Классическая парадигма ООП все еще имеет смысл: выразить в системе типов фундаментальные, неизменные отношения между элементами модели. Здесь фундаментальные неизменные отношения — это "команды выполняются в контексте состояния и правил, и производят набор действий по изменению состояния". Именно с этого и должно было начаться проектирование.



В программе это можно выразить как несколькими способами:
1) framework-based: команды — методы контроллера, бизнес-правила — в виде правил валидации входных данных и функции проверки на выходе, действия — функции изменения состояния в БД с помощью запросов или ORM. (это называется transaction script у фаулера)
2) domain-model: бизнес-правила, команды и исполнители команд — отдельные классы, увязанные через application service, все "внешние" зависимости через отдельные сервисы\репозитарии.
3) functional: команды — АТД, бизнес-правила и исполнители — "чистые" (монадические) функции, применения действия — аналог IO монады, связка всего этого через монадные операторы
Re[7]: Запутался с DDD
Здравствуйте, vaa, Вы писали:

vaa>Здравствуйте, gandjustas, Вы писали:


vaa>>>Очень много нюансов которые сложно обойти чтобы сделать невозможным не валидным состояние агрегата.

G>>Валидность состояния может также завесить от операции. Например нельзя отправить заказ клиенту с некорректным shipping address, но при этом вполне можно принять оплату при заполненном billing address. Такие правила в рамках системы типов выразить невозможно.

G>>Вот серия статей про моделирование предметной области с помощью типов (когда-нибудь я сделаю перевод, потому что статьи прекрасны)

G>>https://ericlippert.com/2015/05/11/wizards-and-warriors-part-five/
vaa>Интересно, в заключении автор изобрел функциональное программирование.
Чем оно функциональное? Ни ФВП, ни АТД, ни иммутабельности нет.

vaa>Не понятно почему он боится исключений. Это такой же способ управлять потоком программы как и if|else.

Исключение это не type safety, из-за которой собственно пытаются городить иерархии классов в стиле DDD. Если ты все сводишь к if-else и исключениям, то тебе не нужны кучи классов.
Об этом и речь в статье.

vaa>К тому же в его коде все время фигурирует void (в этом кстати косяк сеттеров в C# — они void, так что здесь без исключений уже никуда).

И что? Можно код значительно улучшить, не используя void?

vaa>Достаточно из каждого метода изменяющего состояние ввести возврат https://docs.microsoft.com/ru-ru/dotnet/fsharp/language-reference/results

Увы без pattern-matching такой подход не работает. Посмотри на дату статьи.

И еще раз повторю: смысл всех DDD-паттернов — выразить правила и ограничения предметной области в виде классов для compile-time проверки корректности.
Все что уносит нас в рантайм-проверку требует другой архитектуры. Result = Some(x)|None это тоже рантайм проверка.

Липперт в своей статье описал эту архитектуру:

The classic paradigm for OOP still makes perfect sense: encode the fundamental, unchanging relationships between business elements into the type system. Here the fundamental unchanging relationships are things like “commands are evaluated in the context of state and rules, to produce a sequence of actions”, so that’s where the design should have started in the first place.


Перевожу:

Классическая парадигма ООП все еще имеет смысл: выразить в системе типов фундаментальные, неизменные отношения между элементами модели. Здесь фундаментальные неизменные отношения — это "команды выполняются в контексте состояния и правил, и производят набор действий по изменению состояния". Именно с этого и должно было начаться проектирование.



В программе это можно выразить как несколькими способами:
1) framework-based: команды — методы контроллера, бизнес-правила — в виде правил валидации входных данных и функции проверки на выходе, действия — функции изменения состояния в БД с помощью запросов или ORM. (это называется transaction script у фаулера)
2) domain-model: бизнес-правила, команды и исполнители команд — отдельные классы, увязанные через application service, все "внешние" зависимости через отдельные сервисы\репозитарии.
3) functional: команды — АТД, бизнес-правила и исполнители — "чистые" (монадические) функции, применения действия — аналог IO монады, связка всего этого через монадные операторы