DDD: моделирование отношения M: N между двумя корнями, где само отношение несет смысловой смысл - PullRequest
2 голосов
/ 17 марта 2009

Обновление Отредактировано для отражения разъяснений, запрошенных Крисом Холмсом ниже. Первоначально я имел в виду Терминал как сайт, но изменил его, чтобы лучше отражать мой фактический домен.

В глубине души я думаю, что это вопрос о моделировании отношений «многие ко многим» между двумя корневыми объектами, где сами отношения несут некоторый смысловой смысл.

В моем домене

  • Вы можете думать о Терминале как о филиале нашей компании
  • Терминал может иметь отношения с любым количеством клиентов
  • Клиент может иметь отношения с любым количеством терминалов (стандартное множество ко многим)
  • Отношения клиент / терминал означают, что клиент потенциально может хранить продукты в Терминале
  • Эта связь может быть включена \ отключена. Отключение означает лишь то, что вам временно не разрешено хранить продукт, поэтому отключенные отношения совсем не отличаются от отношений вообще.
  • У клиента может быть много офисов
  • Терминал, имеющий отношения с клиентом (включен или нет), должен иметь офис по умолчанию для того клиента, с которым он общается
  • Существуют некоторые настройки по умолчанию, которые применяются ко всем транзакциям между Клиентом и Терминалом, они настроены на уровне Отношения Терминал-Клиент

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

Полагаю, я мог бы сделать переход от Terminal к TerminalCustomerRelationship однонаправленным по отношению к отношениям, но я не знаю, как разорвать отношение от отношения с клиентом, тем более, что оно должно содержать ссылку на Office, который имеет отношения с клиентом.

Я новичок в этом, и хотя большая часть DDD имеет смысл, я запутался и мне нужен свежий взгляд. Может кто-нибудь высказать свое мнение о том, как справиться с этой ситуацией?

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

Ответы [ 3 ]

2 голосов
/ 20 марта 2009

По вашему описанию вам определенно необходим объект " TerminalCustomerRelationship " для отслеживания связанной информации. Я также преобразовал бы флаг ' IsEnabled ' в сущность первого события класса Event с отметкой времени - это дает вам возможность сохранить историю изменений состояния (более реалистичное представление о том, что происходит в домен.)

Вот пример приложения (в VS2008), который решает вашу проблему. Вы можете настроить / протестировать код, пока отношения не будут иметь смысла. Запустите « bin / debug / TerminalSampleApp.exe » и щелкните правой кнопкой мыши « Terminal-> Create Example », чтобы начать.

Дайте мне знать, если вы найдете это полезным.

1 голос
/ 17 марта 2009

Имена часто могут уточнить обязанности объекта и сфокусировать модель предметной области.

Мне неясно, что такое Сайт, и это делает всю модель запутанной, из-за чего мне сложно давать лучшие советы. Например, если бы сайт был поставщиком, то было бы легко переименовать SiteCustomerRelationship в контракт. В этом контексте имеет смысл, чтобы Контракт был его собственной сущностью, а модель была бы похожа на поставщика-контракт-клиента-офис.

Есть и другие способы посмотреть на это. У Уди есть достойный пост о подобных отношениях «многие ко многим» здесь .

0 голосов
/ 17 марта 2009

У вас не должно быть такого объекта, как SiteCustomerRelationship, его конкретной БД.

Если это действительно DDD, вы должны иметь отношение типа:

Aggregate<Site> Customer.Site
IEnumerable<Aggregate<Office>> Customer.Offices

и, возможно,

Aggregate<Office> Customer.DefaultOffice
...