2012-09-11 2 views
2

Все еще экспериментируя с DDD и сомневайтесь, может быть, кто-то мне поможет.DDD: Где поставить логику в корне агрегации

Допустим, что у меня есть 2 модели:

public class Event 
{ 
    User Creator; 
    List<User> Members; 
} 

public class User {} 

Моя проблема в том, что я не могу видеть место для логики, которую я хочу реализовать. Мне нужно 3 действия:

  • Пользователь Записаться на
  • отпуск Пользователь событие
  • Creator удалить пользователя из события (только Творец может удалять пользователей)

На данный момент я только что создал сервис домен EventUserService, который вызывает Event.RemoveUser/AddUser и т. Д. если CurrentUser (предоставлено UserService) является создателем события (имеет права удалить других пользователей). Возможно, этот подход в порядке, но я все же чувствую, что я должен убрать эту логику в корни агрегации, т. Е. :

  • User.JoinEvent (Событие) - я могу добавить прошедшее событие в коллекцию User.Events (bidirectionall) по некоторой логике.
  • User.LeaveEvent (Событие) - аналогично JoinEvent.
  • User.RemoveUserFromEvent (User, Event) - я могу иметь CreatedEvents коллекцию в пользователя и Event из этой коллекции я могу назвать Event.RemoveUser (Пользователь) - так я убедиться, что только создатель может ударить кого-то. or
  • Evet.RemoveUser (UserToRemove) - но как я буду уверен, что его вызвал создатель?

Если первые два метода выглядит нормально (по крайней мере для меня), третий один будет создавать Event.RemoveUser (для управления коллекцией членов Event) метод, который может быть использован для шунтирования логики проживания в User.RemoveUserFromEvent ,

Таким образом, в конце концов, у меня есть 2 вопроса:

  1. Каков Ваш подход в подобной ситуации, когда два агрегатных корни работает вместе, и одна операция определения с помощью логики, проживающего в них обоих? Может быть, какие-то методы вроде User.CanJoinEvent (Event)?
  2. насчет создания «опасности» точки, как User.RemoveUserFromEvent

Может быть кто-то может Бип немного немного света на том, что для меня, каждая помощь будет приятно.

ответ

1
public class Event 
{ 
    User Creator; 
    List<User> Members; 
} 

Не делайте этого.Вы нарушаете Law Of Demeter, а класс Event не имеет контроля над изменениями в Members или пользователями в этом списке. Вы должны определить методы в классе Event, который используется для обработки элементов.

Теперь, если вы сделаете это изменение, то есть что-то вроде этого:

public class Event 
{ 
    User Creator { get private set; } 
    bool IsMember(string name); 
    void AddMember(User user); 
} 

Вы вдруг твердые места, чтобы генерировать события.

но как я буду уверен, что его призвал создатель?

В .NET вы можете использовать Thread.CurrentPrinicpal, чтобы получить информацию о пользователе. Однако он требует, чтобы вы реализовали свои собственные IPrincipal/IIdentity.

Помните: вы должны ВСЕГДА убедиться, что модели находятся в допустимом состоянии в DDD. Это обычно означает, что все сеттеры должны быть частными: http://blog.gauffin.org/2012/06/protect-your-data/

+0

Thx для ответа. После публикации этого вопроса я больше думал о решении, которое я дал мне, об обязанностях и законе, которые вы упомянули. Все еще есть небольшие сомнения в отношении текущего пользователя - разве это не часть инфраструктуры, а затем домена? Но если это так - так как логика дескриптора зависит от текущего пользователя? Передайте текущего пользователя в качестве аргумента и «верьте», что это текущий, а не любой другой пользователь? В моем случае я думал о передаче сервиса аргументом методу вместо использования какого-либо статического свойства. – mgibas

+0

есть. Использование сервиса и передача текущего пользователя - лучшее решение. но imho, IIdentity/IPrincipal находится в .NET и легко настраивается. Я использую его в своих приложениях при проверке материала. – jgauffin

Смежные вопросы