Я нарушаю свои совокупные границы? - PullRequest
8 голосов
/ 09 июля 2009

Я моделирую очень простое приложение ASP.NET MVC, используя NHibernate, и я, похоже, застрял в своем дизайне. Вот эскиз моей модели:

модель 1 http://i29.tinypic.com/309614n.jpg

Как видите, это ОЧЕНЬ просто, но у меня есть некоторые опасения по этому поводу. Корневой объект пользователя и корневой объект организации получают доступ к одному и тому же дочернему объекту Organization_Users через два отношения «один ко многим». Это не кажется правильным, и я думаю, что я нарушаю совокупные границы. Эта модель пахнет для меня, но мне нравится идея, потому что я хотел бы иметь такой код:

var user = userRepository.Load(1);
var list = user.Organizations; // All the organizations the user is a part of.

и

var org = orgRepository.Load(1);
var list = org.Users; // All the users in an organization.

Кроме того, дополнительные данные в таблице, такие как помеченные и роль, будут использоваться организацией. Это плохой дизайн? Если у вас есть какие-либо мысли, это было бы здорово. Я все еще пытаюсь сосредоточиться на мысли о DDD. Спасибо

Ответы [ 6 ]

4 голосов
/ 09 июля 2009

Это типичные отношения «многие ко многим». А таблицы Organization_Users - это таблица мостов. Infact NHibernate и все другие инструменты ORM имеют встроенную функцию поддержки таблицы мостов.

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

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

2 голосов
/ 10 июля 2009

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

var user = userRepository.Load(1);
var list = user.OrganizationUsers; // All the organizations the user is a part of including their role and flagged values.

var organization = list[0].Organization; 

* Если вы собираетесь перебирать все пользовательские организации довольно часто, вам, вероятно, захочется загрузить сущность Organization вместе с OrganzitionUser

Со вторым представленным вами дизайном похоже, что вы сможете добавить пользователя в OrgUserDetails без добавления пользователя в OrganizationUser . Это не похоже на то, что я хотел бы поддержать со своего домена.

2 голосов
/ 09 июля 2009

Я думаю, что ваша модель в порядке. Я обычно думаю о доменных совокупных корнях, когда я думаю о них вообще, с точки зрения того, что публично раскрывается, а не внутренней реализации. С отношениями я думаю о том, какая сущность «носит штаны» в отношениях. То есть более естественно добавить пользователя в организацию или добавить организацию в пользователя? В этом случае оба могут иметь смысл, Пользователь присоединяется к Организации; Организация принимает пользователя к членству.

Если ваш домен видит взаимосвязь с точки зрения Пользователя, вы можете поместить методы для поддержания (добавления, удаления и т. Д.) Взаимосвязи для Пользователя и предоставить доступ к коллекции только для чтения в Организации.

В ответ на ваш второй дизайн (было бы лучше, если бы вы отредактировали исходный вопрос): мне это совсем не нравится. Ваш оригинальный дизайн в порядке. Я не обязательно буду игнорировать базу данных при разработке ваших классов, хороший дизайн должен точно моделировать домен и быть простым для реализации в реляционной базе данных. Иногда вам приходится идти на компромисс в обоих направлениях, чтобы попасть в сладкое место. Там нет тюремного срока за нарушение совокупных границ. : -)

2 голосов
/ 09 июля 2009

Первое, что нужно учитывать в DDD:

  • забудьте вашу схему базы данных (есть нет базы данных!)
  • какие действия вы будете выполнять с этими объектами с точки зрения домена?
1 голос
/ 09 июля 2009

Насколько я понимаю:

Пользователь может принадлежать ко многим организациям. А ТАКЖЕ Организация состоит из 0-ко-многих пользователей.

Правильны ли оба? Если это так, для меня это звучит как многие ко многим.

В многих ко многим вам нужен какой-то объект, похожий на отношения, чтобы преодолеть этот разрыв. Проблема в том, что в домене нет user_organization.

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

С другой стороны, возможно, в вашем домене имеет смысл иметь реестр, который хранит пользователей в организации и хранит их роль и другую информацию, относящуюся к этим отношениям.

0 голосов
/ 09 июля 2009

Спасибо всем за ваши ответы. Они были очень полезны.

Пока я немного больше думал о своей модели, я набросал что-то новое, что, я думаю, будет лучше.

alt text

Я думал так:

  1. Когда пользователь входит на сайт, система находит его учетную запись, а затем возвращает список организаций, в которые они входят, и получает эту информацию от объекта user_organizations.

  2. Когда пользователь нажимает на одну из организаций, которые он разделяет, он направляет их на панель управления организации.

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

Это имеет смысл? :)

Мне кажется, что это было бы хорошо в модели, но у меня есть некоторые сомнения по поводу реализации БД. Я знаю, что мне даже не стоит об этом беспокоиться, но я пока не могу избавиться от своей дурной привычки! Вы можете видеть, что в объекте user_organizations и в объекте org_user_details присутствуют дублированные данные. Я не профессионал БД, но разве это плохой дизайн БД? Должен ли я вместо этого объединить данные из user_organizations и org_user_details в таблицу, подобную той, что была в моем первом посте, и просто сказать NHibernate, что Пользователь смотрит на это как на отношение многие ко многим, а Организация смотрит на это как на отношение один ко многим ? Похоже, я обманываю систему. Извините, если я выглядел очень смущенным по этому поводу.

Что вы думаете об этом? Я слишком обдумываю это? : P

...