Я углубляюсь в концепции доменно-управляемого проектирования (DDD) и обнаружил некоторые странные принципы, особенно в отношении изоляции домена и модели персистентности. Вот мое основное понимание:
- Служба на прикладном уровне (предоставляющая набор функций) запрашивает объекты домена из репозитория, в котором она нуждается для выполнения своей функции.
- Конкретная реализация этого хранилища извлекает данные из хранилища, для которого оно было реализовано
- Служба сообщает объекту домена, который инкапсулирует бизнес-логику, для выполнения определенных задач, которые изменяют его состояние.
- Служба сообщает хранилищу, что нужно сохранить измененный объект домена.
- Хранилище должно отобразить объект домена обратно в соответствующее представление в хранилище.
Теперь, учитывая вышеизложенные предположения, следующее кажется неловким:
Объявление 2 .:
Кажется, что модель домена загружает весь объект домена (включая все поля и ссылки), даже если они не нужны для запрашивающей его функции. Полная загрузка может быть невозможна даже при ссылке на другие объекты домена, если только вы не загрузите эти объекты домена, а также все объекты, на которые они ссылаются по очереди, и так далее, и так далее. На ум приходит ленивая загрузка, что означает, что вы начинаете запрашивать объекты вашего домена, что в первую очередь должно быть обязанностью репозитория.
Учитывая эту проблему, «правильный» способ загрузки объектов домена, кажется, имеет выделенную функцию загрузки для каждого варианта использования. Эти выделенные функции будут загружать только те данные, которые требуются для варианта использования, для которого они были разработаны. Вот где неловкость вступает в игру: во-первых, мне пришлось бы поддерживать значительное количество функций загрузки для каждой реализации репозитория, и доменные объекты могли бы оказаться в незавершенных состояниях, несущих null
в своих полях. Последнее технически не должно быть проблемой, потому что, если значение не было загружено, оно не должно требоваться функциональностью, которая его запрашивала. Тем не менее, это неловко и потенциальная опасность.
Объявление 3 .:
Каким образом объект домена проверяет ограничения уникальности при построении, если он не имеет никакого представления о хранилище? Например, если бы я хотел создать новый User
с уникальным номером социального страхования (который указан), самый ранний конфликт возник бы при запросе хранилища сохранить объект, только если в базе данных определено ограничение уникальности. В противном случае, я мог бы искать User
с данным социальным обеспечением и сообщить об ошибке, если она существует, прежде чем создавать новую. Но тогда проверки ограничений будут жить в службе, а не в объекте домена, к которому они принадлежат. Я только что понял, что объектам домена очень хорошо разрешено использовать (проверенные) репозитории для проверки.
Объявление 5 .:
Я воспринимаю сопоставление объектов домена с серверной частью хранилища как трудоемкий процесс по сравнению с тем, чтобы объекты домена непосредственно изменяли лежащие в основе данные. Это, конечно, важная предпосылка для отделения конкретной реализации хранилища от кода домена. Однако действительно ли это так дорого?
По-видимому, у вас есть возможность использовать инструменты ORM, чтобы сделать сопоставление для вас. Однако для этого часто требуется разработать модель домена в соответствии с ограничениями ORM или даже ввести зависимость от уровня домена до уровня инфраструктуры (например, с помощью аннотаций ORM в объектах домена). Также я читал, что ORM вносят значительные вычислительные затраты.
В случае баз данных NoSQL, для которых едва ли существуют какие-либо ORM-подобные концепции, как вы отслеживаете, какие свойства изменились в доменных моделях save()
?
Редактировать : Кроме того, для того, чтобы репозиторий мог получить доступ к состоянию объекта домена (т.е. к значению каждого поля), объекту домена необходимо выявить свое внутреннее состояние, которое нарушает инкапсуляцию.
В основном:
- Куда пошла бы транзакционная логика? Это, конечно, специфичность постоянства. Некоторая инфраструктура хранения может вообще не поддерживать транзакции (например, репозитории в памяти).
- Для массовых операций, которые изменяют несколько объектов, должен ли я загружать, изменять и хранить каждый объект по отдельности, чтобы пройти инкапсулированную логику проверки объекта? Это противоположно выполнению одного запроса непосредственно к базе данных.
Буду признателен за разъяснения по этой теме. Верны ли мои предположения? Если нет, как правильно решить эти проблемы?