При проектировании, ориентированном на домен...
Я согласен с @Flater в этом вопросе. DDD - это в основном про домен как вездесущий язык, т.е. используемый везде, в том числе и в коде. Он в меньшей степени относится к этим сущностям-значениям-хранилищам-сервисам. Последние - лишь одна из интерпретаций, даже согласно книге. Я лично считаю, что это даже не очень хорошая интерпретация.
Выражение области является наивысшим приоритетом. А не техническая категоризация и детали.
Хранилище - это коллекция, подобная "интерфейсу", которая скрывает доступ к источнику данных. Он предоставляет методы добавления, удаления и извлечения данных точно так же, как и коллекция. Он делает это, используя язык домена.
Это противоречие. Если ваш домен не связан с CRUD (т.е. вы являетесь базой данных), то add/remove/delete/etc. не будет частью языка домена.
Домен Account
не "обновляется". Деньги переводятся, он закрывается и т.д. Эти операции подразумевают персистентность, но персистентность - это техническая сторона дела.
Прикладной уровень использует хранилища, рассматривая их как коллекции, извлекая из них или добавляя в них элементы, но не должен знать, сохраняется ли конкретный элемент или нет.
Звучит ли это как язык домена? Нет, не похоже. Это технология. Технология должна быть скрыта, "домен" должен быть виден.
С учетом этих правил: Как можно сохранять обновления сущностей и должно ли хранилище возвращать самосохраняющиеся сущности?
Это странно сформулированный вопрос. Должны ли возвращаемые объекты быть "самоподдерживающимися"? Это технический вопрос, поэтому он не должен существенно влиять на дизайн. На самом деле вопрос заключается в том, подразумевает ли какой-то сценарий использования, который я хочу выразить, постоянство.
Если я инициирую денежный перевод, я ожидаю, что он будет настойчивым. Возможно. Если я добавляю два Money
объекта, я этого не делаю. Возможно, в зависимости от домена.
Вы не можете думать о хранилище как о коллекции, теперь это абстракция над персистентностью. Это, имо, очень отличная концепция от первоначального замысла репозиториев.
Я согласен, это не то, что подразумевается в книге, и это также не имеет смысла. Постоянство - это техническая сторона, оно не является частью повсеместного языка (в большинстве случаев).
Второе решение, которое я видел, - это использование ORM-фреймворка и добавление кучи аннотаций в доменном слое. На ум приходит @Entity(). Я считаю, что это худшее решение из всех, так как оно загрязняет доменную среду.
Согласен, это очень плохо.
Третье решение, которое я не видел, - это возвращать PersistedOrder вместо заказа на прикладной уровень.
Как упоминалось в комментариях, это несколько похоже на ActiveRecords, но все же полностью упускает суть.
Наличие "записей" в первую очередь, то есть пакетов данных, которые нужно извлекать и сохранять в базе данных, полностью противоречит объектной ориентации и DDD.
Записи базы данных не относятся к домену, не являются частью вездесущего языка, поэтому они вообще не должны иметь значения для целей проектирования.
Правильной альтернативой является моделирование домена. Как есть. С персистентностью там, где она подразумевается. Даже с пользовательским интерфейсом, где он подразумевается. Со всем. Разговор с экспертом домена / пользователем не остановится на технических границах. Технические границы не существуют (опять же, ymmv) в домене. Пользователи будут говорить о Account
и его UI взаимозаменяемо.
Если вы ищете название для этого, то иногда это называется "богатый домен". Внимание, название не соответствует действительности, иногда люди не имеют в виду вышеуказанное, когда ссылаются на rich domain.
HTH
Рекомендую посмотреть эти видео для лучшего погружения в вопрос: