Как смоделировать отношения объекта значения? - PullRequest
1 голос
/ 18 декабря 2009

Контекст:
У меня есть книга сущностей. Книга может иметь одно или несколько описаний. Описания являются объектами значения.

Проблема:
Описание может быть более конкретным, чем другое описание. Например, если описание содержит содержание книги и то, как выглядит обложка, она более конкретна, чем описание, в котором обсуждается только то, как выглядит обложка. Я не знаю, как смоделировать это и как сохранить репозиторий. Это не обязанность книги или описания книги, чтобы знать эти отношения. Некоторый другой объект может обработать это и затем попросить хранилище сохранить отношения. Но BookRepository.addMoreSpecificDescription (Description, MoreSpecificDescription) кажется трудным для сохранения в хранилище.

Как такое обрабатывается в DDD?

Ответы [ 3 ]

7 голосов
/ 22 декабря 2009

Два других ответа - одно направление (+1 к слову). Я прихожу после того, как вы отредактируете исходный вопрос, вот мои два цента ...

Я определяю Объект значения как объект с двумя или более свойствами, которые могут (и есть) совместно использоваться другими объектами. Они могут быть разделены только в пределах одного Агрегированного Корня, это тоже хорошо. Просто тот факт, что они могут (и являются) общими.

Чтобы использовать ваш пример, вы определяете «Описание» как Объект Значения. Это говорит мне о том, что «Описание» с несколькими свойствами может быть общим для нескольких Книг. В реальном мире это не имеет смысла, поскольку все мы знаем, что каждая книга имеет уникальные описания, написанные мастером, который написал или опубликовал книгу. Хехе. Итак, я бы сказал, что описания на самом деле не являются объектами значений, а сами являются дополнительными объектами сущности в пределах границ вашей совокупной корневой сущности книги (вы можете иметь несколько сущностей в пределах одной совокупной корневой сущности). Даже переизданные книги, более новая редакция и т. Д. Имеют немного отличающиеся описания, описывающие это небольшое изменение.

Я полагаю, что это ответит на ваш вопрос - создайте описания объектов-сущностей и защитите их за основным корнем объекта сущности книги (например, Book.GetDescription () ...). Остальная часть этого ответа посвящена тому, как я работаю с объектами-значениями в репозиториях, для тех, кто читает этот пост ...

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

В домене, управляемом дизайном, вы моделируете объекты значения в своем домене, а не в хранилище данных. Это ключевая фраза. Это означает, что вы не проектируете объекты-значения, которые будут храниться как независимые объекты в хранилище данных, вы можете хранить их по своему усмотрению!

Давайте возьмем общий DDD-пример Value Objects, который является Address (). DDD представляет, что почтовый адрес является идеальным примером объекта-значения, поскольку определение объекта-значения - это объект, свойства которого суммируют, чтобы создать уникальность объекта. Если свойство изменяется, это будет другой объект значения. И тот же объект Value (сумма его свойств) может быть разделен между другими сущностями.

Почтовый адрес - это местоположение, длинный / лат определенного места на планете. По этому адресу могут жить несколько человек, и когда кто-то переезжает, новые люди, занимающие один и тот же почтовый адрес, теперь используют один и тот же объект значения.

Итак, у меня есть объект Person () с объектом MailingAddress (), в котором есть информация об адресе. Он защищен моим агрегатным корнем Person () с помощью методов / сервисов get / update / create.

Теперь, как мы можем хранить это и делиться этим среди людей в одном доме? Ах, в этом заключается DDD - вы не моделируете свое хранилище данных прямо из DDD (хотя это было бы неплохо). При этом вы просто создаете одну таблицу, которая представляет ваш объект Person, и в нем есть столбцы для вашего почтового адреса. Работа вашего репозитория заключается в том, чтобы повторно гидрировать эту информацию обратно в ваш объект Person () и MailingAddress () из хранилища данных и разделить ее во время операций создания / обновления.

Да, у вас сейчас есть дубликаты в вашем хранилище данных. Три объекта Person () с одним и тем же почтовым адресом теперь имеют три отдельные копии данных этого объекта-значения - и это нормально! Объекты-значения предназначены для копирования и удаления довольно легко. «Копия» - это оптимальное слово в пьесе DDD.

Подводя итог, можно сказать, что Domain Drive Design - это моделирование вашего Домена для представления фактического бизнес-использования объектов. Вы моделируете сущность Person () и объект значения MailingAddress по отдельности, так как они представлены в вашем приложении по-разному. Вы сохраняете им скопированные данные, которые являются дополнительными столбцами в той же таблице, что и ваша таблица Person.

Все вышеперечисленное строго-DDD. Но DDD - это просто «предложения», а не правила, по которым нужно жить. Вот почему вы свободны делать то, что сделали я и многие другие, что-то вроде стиля DDD. Если вам не нравятся скопированные данные, вы можете создать отдельную таблицу для MailingAddress () и прикрепить к ней столбец Identity, а также обновить свой объект MailingAddress (), чтобы теперь иметь эту идентификацию - зная, что вы используете эту идентификацию только для связывания ее с другими объектами Person (), которые ее разделяют (лично мне нравится третья таблица отношений «многие ко многим», чтобы поддерживать скорость запросов). Вы бы замаскировали эту Идентичность (то есть внутренний модификатор) от раскрытия вне вашего Агрегированного Корня / Домена, чтобы другие слои (такие как Приложение или Пользовательский интерфейс) не знали столбец Идентичности MailingAddress, если это возможно. Кроме того, я бы создал специальный репозиторий только для MailingAddress и использовал бы ваш слой PersonService, чтобы объединить их в правильный объект Person.MailingAddress ().

Извините за напыщенную речь ...:)

4 голосов
/ 18 декабря 2009

Во-первых, я думаю, что отзывы должны быть сущностями.

Во-вторых, почему вы пытаетесь смоделировать отношения между обзорами? Я не вижу естественных отношений между ними. «Более конкретно чем» слишком расплывчато, чтобы быть полезным в качестве отношений.

Если вы испытываете трудности с моделированием ситуации, это говорит о том, что, возможно, нет никакой связи.

1 голос
/ 18 декабря 2009

Я согласен с Джейсоном. Я не знаю, каково ваше обоснование для создания объектов оценки отзывов.

Я ожидаю, что BookReview будет иметь BookReviewContentItems, чтобы вы могли иметь метод в BookReview для вызова, чтобы определить, достаточно ли он специфичен, где метод решается на основе запроса своей коллекции элементов контента.

...