DDD Генерация идентификаторов для сущностей и транзитивная бизнес-логика
DDD Генерация идентификаторов для сущностей и транзитивная бизнес-логика
Рефакторим старый проект. Ключи - целочисленные.
Стараемся использовать лучшие практики DDD. Бизнес-логику размещаем в доменной модели - сущностях и сервисах. Появилась проблема.
Создание сущности многоэтапный процесс (такая предметная область). До сохранения нужно много чего посчитать (на основе введенных данных) и много чего показать пользователю перед нажатием кнопки "Сохранить"
При выполнении подсчетов алгоритм такой
1. в контроллер приходят данные (AJAX)
2. контроллер делает dto и вызывает прикладную службу.
3. прикладная служба создает сущность и заливает туда данные.
4. прикладная служба вызывает методы, которые считают, что нужно.
5. прикладная служба возвращает сущность контроллеру (можно и dto вернуть, сейчас не об этом).
6. контроллер формирует ответ.
Т.е. персистентности нет.
При нажатии "Сохранить" делается в том числе то же самое, но уже с персистентностью.
ПРОБЛЕМА
Сущность в конструкторе требует идентификатор. Для совместимости со старой базой он генерится с помощью отдельной таблицы и SELECT FOR UDPATE, естественно, все это завернуто в абстракцию.
Пользователи любят потыкать и посмотреть что и как меняется. Будет уходить много айдишников да и в БД запросы лишние.
Я понимаю, что c uuid этой проблемы вообще не будет - но есть старая БД - генерить для всех uuid не хочется, да и надо обеспечить совместимость по данным со старым кодом и другими приложениями, работающими с той же бд - рефакторить все и сразу - убъемся.
ВОПРОСЫ
Корректно ли так использовать сущности (для предварительного расчета, без персистентности) или надо все это в сервисы без состояния?
Может лучше, если я id сделаю необязательным в конструкторе, буду его передавать только там, где сущность будет сохраняться и где нужны доменные события, в общем где нужно? Внутри везде понатыкаю проверок на наличие id?
Или лучше id-шкники и запросы в БД не жалеть (с UNSIGNED BIGINT они вряд-ли кончатся)?
Кто так справлялся с подобными проблемами?
Стараемся использовать лучшие практики 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 Генерация идентификаторов для сущностей и транзитивная бизнес-логика
> При нажатии "Сохранить" делается в том числе то же самое, но уже с персистентностью.
Если я правильно понял, то тут две сущности, до и после "Сохранить".
Основная характеристика сущности это жизненный цикл.
В примере, первый жизненный цикл заканчивается в момент нажатия "Сохранить" и начинается другой.
Для обоих сущностей вполне подойдет один класс (интерфейс), но с разными идентификаторами.
Если я правильно понял, то тут две сущности, до и после "Сохранить".
Основная характеристика сущности это жизненный цикл.
В примере, первый жизненный цикл заканчивается в момент нажатия "Сохранить" и начинается другой.
Для обоих сущностей вполне подойдет один класс (интерфейс), но с разными идентификаторами.
Жду Yii 3!
Re: DDD Генерация идентификаторов для сущностей и транзитивная бизнес-логика
Про жц здорово подсказали, спасибо.
Получается класс один, идентификаторы разные. В транзитивном объекте свой - на каждый запрос, в персистентном свой.
Получается класс один, идентификаторы разные. В транзитивном объекте свой - на каждый запрос, в персистентном свой.
-
- Сообщения: 6
- Зарегистрирован: 2017.03.31, 20:07
Re: DDD Генерация идентификаторов для сущностей и транзитивная бизнес-логика
> Создание сущности многоэтапный процесс
В голову сразу пришел билдер. В добавок сущность без идентификатора по определению невалидна.
В голову сразу пришел билдер. В добавок сущность без идентификатора по определению невалидна.
Re: DDD Генерация идентификаторов для сущностей и транзитивная бизнес-логика
Под многоэтапным процессом имелось ввиду взаимодействие с пользователем:frostealth писал(а): ↑2017.05.05, 15:07 > Создание сущности многоэтапный процесс
В голову сразу пришел билдер. В добавок сущность без идентификатора по определению невалидна.
Грубо: Пользователь что-то заполняет, нажимает "Далее >>", в зависимости от введенных данных ему приходят новые поля ввода и что-то считается и показывается и так далее до "Сохранить".
- slavcodev
- Сообщения: 3134
- Зарегистрирован: 2009.04.02, 21:42
- Откуда: Valencia
- Контактная информация:
Re: DDD Генерация идентификаторов для сущностей и транзитивная бизнес-логика
Так без идентификатора в принципе невозможен "многоэтапный процесс" в несколько запросов от клиента.frostealth писал(а): ↑2017.05.05, 15:07 В добавок сущность без идентификатора по определению невалидна.
Жду Yii 3!
-
- Сообщения: 6
- Зарегистрирован: 2017.03.31, 20:07
Re: DDD Генерация идентификаторов для сущностей и транзитивная бизнес-логика
"Сохранить" - это финальная точка процесса. Использовать билдер, менять состояние сущности или просто собирать необходимые для сущности данные пошагово - зависит от контекста.anton_z писал(а): ↑2017.05.05, 15:18Под многоэтапным процессом имелось ввиду взаимодействие с пользователем:frostealth писал(а): ↑2017.05.05, 15:07 > Создание сущности многоэтапный процесс
В голову сразу пришел билдер. В добавок сущность без идентификатора по определению невалидна.
Грубо: Пользователь что-то заполняет, нажимает "Далее >>", в зависимости от введенных данных ему приходят новые поля ввода и что-то считается и показывается и так далее до "Сохранить".
Из ваших слов следует, что все шаги служат для сбора и подготовки данных, необходимых для создания сущности, а не модификации ее состояния уже после создания валидной сущности. Билдер как раз и служит для создания объекта в несколько шагов и позволяет создать его с разными свойствами.
Насколько я понял, у вас на каждый шаг создается новая сущность, которая не нужна вовсе - отсюда и проблемы.При выполнении подсчетов алгоритм такой
1. в контроллер приходят данные (AJAX)
2. контроллер делает dto и вызывает прикладную службу.
3. прикладная служба создает сущность и заливает туда данные.
4. прикладная служба вызывает методы, которые считают, что нужно.
5. прикладная служба возвращает сущность контроллеру (можно и dto вернуть, сейчас не об этом).
6. контроллер формирует ответ.
Т.е. персистентности нет.
При нажатии "Сохранить" делается в том числе то же самое, но уже с персистентностью.
В данном случае стоит либо воспользоваться билдером и пошагово заполнять его, производя необходимые вычисления с помощью сервисов, либо определить корректное состояние сущности на первом этапе, сохранить ее и далее менять ее состояние до необходимого.
-
- Сообщения: 6
- Зарегистрирован: 2017.03.31, 20:07
Re: DDD Генерация идентификаторов для сущностей и транзитивная бизнес-логика
А для чего идентификатор нужен? Идентификатор нужен только тогда, когда сущность уже существует и хранится.slavcodev писал(а): ↑2017.05.05, 18:18Так без идентификатора в принципе невозможен "многоэтапный процесс" в несколько запросов от клиента.frostealth писал(а): ↑2017.05.05, 15:07 В добавок сущность без идентификатора по определению невалидна.
Нужно же идентифицировать только клиента и куда-нибудь положить эти данные, хотя клиент может сам собрать необходимые данные и отправить их серверу одним запросом.
Re: DDD Генерация идентификаторов для сущностей и транзитивная бизнес-логика
Да, так и промсходит. Клиент собирает, но по ходу дела ему нужны результаты предварительных рассчетов.. Рассчеты делает сущность.
Re: DDD Генерация идентификаторов для сущностей и транзитивная бизнес-логика
Нет, идентификатор это не понятие системы хранения, это понятие бизнеса. У любой сущности, которая даже после запроса будет уничтожена, должен быть идентификатор
-
- Сообщения: 6
- Зарегистрирован: 2017.03.31, 20:07
Re: DDD Генерация идентификаторов для сущностей и транзитивная бизнес-логика
Идентификатор - это не совсем понятие бизнеса, это понятие идентификации. Сущность же имеет индивидуальное и непрерывное существование и ее необходимо идентифицировать. У вас же сущность создается только ради проведения неких расчетов для отображения, а это явно уже некорректное использование сущности.Корректно ли так использовать сущности (для предварительного расчета, без персистентности) или надо все это в сервисы без состояния?
Не будем же создавать сущность Order ради подсчета общей стоимости товаров в корзине?
Re: DDD Генерация идентификаторов для сущностей и транзитивная бизнес-логика
Заказ это заказ, корзина это корзина. Разные понятия, разные алгоритмы подсчета.
У меня алгоритм один. Он потом используется и для пересчетов при редактировании сущности. Этот алгоритм работает на одних и тех же данных, отличие в отсутствии идентификатора.
Ваша позиция понятна. Попробую сделать прототип, переложив логику на доменные сервисы.
У меня алгоритм один. Он потом используется и для пересчетов при редактировании сущности. Этот алгоритм работает на одних и тех же данных, отличие в отсутствии идентификатора.
Ваша позиция понятна. Попробую сделать прототип, переложив логику на доменные сервисы.