Различные репозитории сохраняемости для агрегата в DDD

У меня есть агрегат с корневым объектом (Документация) и VO (Документ). Документы связаны с файлами (pdf, изображения, офисные документы и т. д.), поэтому мне приходится сохранять совокупность в базе данных и файлы на ftp-сервере (файлы не могут быть сохранены в базе данных, поскольку объем файлов слишком велик). Мой класс репозитория db реализует интерфейс с такими методами, как FindXXX, AddDocument, RemoveDocument и другими. Как я могу реализовать постоянство ftp? Должен ли мой репозиторий db подключаться к ftp setver в AddDocument и RemoveDocument? Или я должен создать класс репозитория ftp, который реализует интерфейс. Если это так, то методы вроде FindXXX не имеют смысла. Насколько я знаю о DDD, у каждого агрегата есть только один репозиторий интерфейса, который представляет, как можно сохранять. Он может иметь несколько «режимов сохранения» (в базе данных, ftp, файле и т. д.), но интерфейс должен быть одинаковым.


person user1151816    schedule 02.02.2018    source источник


Ответы (2)


Насколько я знаю о DDD, у каждого агрегата есть только один репозиторий интерфейса, который представляет, как можно сохранять.

В основном это правда; люди обычно предполагают, что весь агрегат будет храниться в одном месте. Когда вы распределяете состояние агрегата по нескольким единицам хранения, режимы отказа требуют особого внимания.

Итак, нужно учитывать, являются ли отдельно хранящиеся документы чем-то, что является частью агрегата, или чем-то, на что агрегат ссылается.

Если агрегат ссылается на них, то вы рассматриваете их как любую другую ссылку на другой агрегат. Агрегат документации хранит идентификатор/ссылку/подсказку для документа и использует службу домена для доступа к документу, если он ему нужен.

Если они являются частью совокупности, то обычным ответом будет то, что "репозиторий" будет фасадом перед сложной инфраструктурой, которая маскирует тот факт, что документация и документ(ы) хранятся отдельно.

Другими словами, уровень инфраструктуры будет пытаться организовать операции загрузки и сохранения, а остальной части системы не нужно знать подробности.

person VoiceOfUnreason    schedule 02.02.2018
comment
Ммм.. интересный вопрос. И я не уверен. Частично это часть совокупности, потому что файл (класс Document VO) является частью объекта Documentation. Но, с другой стороны, когда я выполняю метод FindXXX в репозитории, я не загружаю все документы на ftp-сайте, а загружаю только информацию из базы данных. Я не уверен, что это правильный ответ. - person user1151816; 02.02.2018

Поздний ответ. Но, проще говоря, у вас должно быть два сервиса. В моем понимании DDD репозитории часто рассматриваются как службы инфраструктуры. В этом случае у вас есть два:

  1. Репозиторий/интерфейс для хранения и базового поиска идентификаторов документов, метаданных и ссылок.
  2. Репозиторий/интерфейс для хранения и базового поиска больших двоичных объектов данных.

Иногда имеет смысл иметь несколько агрегатов и репозиториев. Фактически, некоторые примеры Вона Вернона в ограниченных контекстах (https://github.com/VaughnVernon/IDDD_Samples) включать агрегаты, содержащие ссылки на другие агрегаты. Я бы сказал, что вы должны делать то, что имеет смысл и кажется уместным.

Действительно, если вы управляете центром сбора почтовых отправлений, скорее всего, у вас будет способ 1. хранить посылки от маленьких до больших и 2. составлять указатель того, где в центре находятся все посылки от маленьких до больших, чтобы вы может получить его.

Мой класс репозитория db реализует интерфейс с такими методами, как FindXXX, AddDocument, RemoveDocument и другими. Как я могу реализовать постоянство ftp? Должен ли мой репозиторий db подключаться к ftp setver в AddDocument и RemoveDocument? Или я должен создать класс репозитория ftp, который реализует интерфейс.

Если ваш репозиторий базы данных подключается к FTP в дополнение к какому-либо другому хранилищу данных, возможно, вы возлагаете слишком много логики и ответственности на одну область. Тем не менее, в этом тоже нет ничего плохого.

Если это так, то методы вроде FindXXX не имеют смысла. Насколько я знаю о DDD, у каждого агрегата есть только один репозиторий интерфейса, который представляет, как можно сохранять.

Для этой конкретной проблемы большинство практиков DDD порекомендуют вам иметь отдельную службу/модель представления. Он может создавать материализованный/представленный DTO для репозиториев или сервисов.

По сути, должно быть легко тестировать отдельные части и заменять базовые реализации. Если вы однажды решили переключиться (или даже включить поддержку) с FTP на Google Cloud Storage / AWS S3, то может потребоваться дополнительная работа и изменения в тестовых примерах.

person MrSaints    schedule 12.02.2019