DDD Генерация идентификаторов для сущностей и транзитивная бизнес-логика

Обсуждаем, как правильно строить приложения
Ответить
anton_z
Сообщения: 483
Зарегистрирован: 2017.01.15, 15:01

DDD Генерация идентификаторов для сущностей и транзитивная бизнес-логика

Сообщение anton_z »

Рефакторим старый проект. Ключи - целочисленные.

Стараемся использовать лучшие практики DDD. Бизнес-логику размещаем в доменной модели - сущностях и сервисах. Появилась проблема.

Создание сущности многоэтапный процесс (такая предметная область). До сохранения нужно много чего посчитать (на основе введенных данных) и много чего показать пользователю перед нажатием кнопки "Сохранить"

При выполнении подсчетов алгоритм такой
1. в контроллер приходят данные (AJAX)
2. контроллер делает dto и вызывает прикладную службу.
3. прикладная служба создает сущность и заливает туда данные.
4. прикладная служба вызывает методы, которые считают, что нужно.
5. прикладная служба возвращает сущность контроллеру (можно и dto вернуть, сейчас не об этом).
6. контроллер формирует ответ.

Т.е. персистентности нет.

При нажатии "Сохранить" делается в том числе то же самое, но уже с персистентностью.

ПРОБЛЕМА

Сущность в конструкторе требует идентификатор. Для совместимости со старой базой он генерится с помощью отдельной таблицы и SELECT FOR UDPATE, естественно, все это завернуто в абстракцию.

Пользователи любят потыкать и посмотреть что и как меняется. Будет уходить много айдишников да и в БД запросы лишние.

Я понимаю, что c uuid этой проблемы вообще не будет - но есть старая БД - генерить для всех uuid не хочется, да и надо обеспечить совместимость по данным со старым кодом и другими приложениями, работающими с той же бд - рефакторить все и сразу - убъемся.

ВОПРОСЫ

Корректно ли так использовать сущности (для предварительного расчета, без персистентности) или надо все это в сервисы без состояния?

Может лучше, если я id сделаю необязательным в конструкторе, буду его передавать только там, где сущность будет сохраняться и где нужны доменные события, в общем где нужно? Внутри везде понатыкаю проверок на наличие id?

Или лучше id-шкники и запросы в БД не жалеть (с UNSIGNED BIGINT они вряд-ли кончатся)?

Кто так справлялся с подобными проблемами?
Аватара пользователя
slavcodev
Сообщения: 3134
Зарегистрирован: 2009.04.02, 21:42
Откуда: Valencia
Контактная информация:

Re: DDD Генерация идентификаторов для сущностей и транзитивная бизнес-логика

Сообщение slavcodev »

> При нажатии "Сохранить" делается в том числе то же самое, но уже с персистентностью.

Если я правильно понял, то тут две сущности, до и после "Сохранить".
Основная характеристика сущности это жизненный цикл.
В примере, первый жизненный цикл заканчивается в момент нажатия "Сохранить" и начинается другой.
Для обоих сущностей вполне подойдет один класс (интерфейс), но с разными идентификаторами.
Жду Yii 3!
anton_z
Сообщения: 483
Зарегистрирован: 2017.01.15, 15:01

Re: DDD Генерация идентификаторов для сущностей и транзитивная бизнес-логика

Сообщение anton_z »

Про жц здорово подсказали, спасибо.
Получается класс один, идентификаторы разные. В транзитивном объекте свой - на каждый запрос, в персистентном свой.
frostealth
Сообщения: 6
Зарегистрирован: 2017.03.31, 20:07

Re: DDD Генерация идентификаторов для сущностей и транзитивная бизнес-логика

Сообщение frostealth »

> Создание сущности многоэтапный процесс

В голову сразу пришел билдер. В добавок сущность без идентификатора по определению невалидна.
anton_z
Сообщения: 483
Зарегистрирован: 2017.01.15, 15:01

Re: DDD Генерация идентификаторов для сущностей и транзитивная бизнес-логика

Сообщение anton_z »

frostealth писал(а): 2017.05.05, 15:07 > Создание сущности многоэтапный процесс

В голову сразу пришел билдер. В добавок сущность без идентификатора по определению невалидна.
Под многоэтапным процессом имелось ввиду взаимодействие с пользователем:
Грубо: Пользователь что-то заполняет, нажимает "Далее >>", в зависимости от введенных данных ему приходят новые поля ввода и что-то считается и показывается и так далее до "Сохранить".
Аватара пользователя
slavcodev
Сообщения: 3134
Зарегистрирован: 2009.04.02, 21:42
Откуда: Valencia
Контактная информация:

Re: DDD Генерация идентификаторов для сущностей и транзитивная бизнес-логика

Сообщение slavcodev »

frostealth писал(а): 2017.05.05, 15:07 В добавок сущность без идентификатора по определению невалидна.
Так без идентификатора в принципе невозможен "многоэтапный процесс" в несколько запросов от клиента.
Жду Yii 3!
frostealth
Сообщения: 6
Зарегистрирован: 2017.03.31, 20:07

Re: DDD Генерация идентификаторов для сущностей и транзитивная бизнес-логика

Сообщение frostealth »

anton_z писал(а): 2017.05.05, 15:18
frostealth писал(а): 2017.05.05, 15:07 > Создание сущности многоэтапный процесс

В голову сразу пришел билдер. В добавок сущность без идентификатора по определению невалидна.
Под многоэтапным процессом имелось ввиду взаимодействие с пользователем:
Грубо: Пользователь что-то заполняет, нажимает "Далее >>", в зависимости от введенных данных ему приходят новые поля ввода и что-то считается и показывается и так далее до "Сохранить".
"Сохранить" - это финальная точка процесса. Использовать билдер, менять состояние сущности или просто собирать необходимые для сущности данные пошагово - зависит от контекста.
Из ваших слов следует, что все шаги служат для сбора и подготовки данных, необходимых для создания сущности, а не модификации ее состояния уже после создания валидной сущности. Билдер как раз и служит для создания объекта в несколько шагов и позволяет создать его с разными свойствами.
При выполнении подсчетов алгоритм такой
1. в контроллер приходят данные (AJAX)
2. контроллер делает dto и вызывает прикладную службу.
3. прикладная служба создает сущность и заливает туда данные.
4. прикладная служба вызывает методы, которые считают, что нужно.
5. прикладная служба возвращает сущность контроллеру (можно и dto вернуть, сейчас не об этом).
6. контроллер формирует ответ.

Т.е. персистентности нет.

При нажатии "Сохранить" делается в том числе то же самое, но уже с персистентностью.
Насколько я понял, у вас на каждый шаг создается новая сущность, которая не нужна вовсе - отсюда и проблемы.
В данном случае стоит либо воспользоваться билдером и пошагово заполнять его, производя необходимые вычисления с помощью сервисов, либо определить корректное состояние сущности на первом этапе, сохранить ее и далее менять ее состояние до необходимого.
frostealth
Сообщения: 6
Зарегистрирован: 2017.03.31, 20:07

Re: DDD Генерация идентификаторов для сущностей и транзитивная бизнес-логика

Сообщение frostealth »

slavcodev писал(а): 2017.05.05, 18:18
frostealth писал(а): 2017.05.05, 15:07 В добавок сущность без идентификатора по определению невалидна.
Так без идентификатора в принципе невозможен "многоэтапный процесс" в несколько запросов от клиента.
А для чего идентификатор нужен? Идентификатор нужен только тогда, когда сущность уже существует и хранится.

Нужно же идентифицировать только клиента и куда-нибудь положить эти данные, хотя клиент может сам собрать необходимые данные и отправить их серверу одним запросом.
anton_z
Сообщения: 483
Зарегистрирован: 2017.01.15, 15:01

Re: DDD Генерация идентификаторов для сущностей и транзитивная бизнес-логика

Сообщение anton_z »

Да, так и промсходит. Клиент собирает, но по ходу дела ему нужны результаты предварительных рассчетов.. Рассчеты делает сущность.
anton_z
Сообщения: 483
Зарегистрирован: 2017.01.15, 15:01

Re: DDD Генерация идентификаторов для сущностей и транзитивная бизнес-логика

Сообщение anton_z »

Нет, идентификатор это не понятие системы хранения, это понятие бизнеса. У любой сущности, которая даже после запроса будет уничтожена, должен быть идентификатор
frostealth
Сообщения: 6
Зарегистрирован: 2017.03.31, 20:07

Re: DDD Генерация идентификаторов для сущностей и транзитивная бизнес-логика

Сообщение frostealth »

anton_z писал(а): 2017.05.06, 03:07 Нет, идентификатор это не понятие системы хранения, это понятие бизнеса. У любой сущности, которая даже после запроса будет уничтожена, должен быть идентификатор
Корректно ли так использовать сущности (для предварительного расчета, без персистентности) или надо все это в сервисы без состояния?
Идентификатор - это не совсем понятие бизнеса, это понятие идентификации. Сущность же имеет индивидуальное и непрерывное существование и ее необходимо идентифицировать. У вас же сущность создается только ради проведения неких расчетов для отображения, а это явно уже некорректное использование сущности.

Не будем же создавать сущность Order ради подсчета общей стоимости товаров в корзине?
anton_z
Сообщения: 483
Зарегистрирован: 2017.01.15, 15:01

Re: DDD Генерация идентификаторов для сущностей и транзитивная бизнес-логика

Сообщение anton_z »

Заказ это заказ, корзина это корзина. Разные понятия, разные алгоритмы подсчета.
У меня алгоритм один. Он потом используется и для пересчетов при редактировании сущности. Этот алгоритм работает на одних и тех же данных, отличие в отсутствии идентификатора.
Ваша позиция понятна. Попробую сделать прототип, переложив логику на доменные сервисы.
Ответить