DDD: Как следует моделировать добавление и удаление связанных объектов? - PullRequest
2 голосов
/ 29 апреля 2009

Скажем, у нас есть две совокупные корни в модели домена: группа и пользователь.

Теперь пользователи могут быть добавлены или удалены из групп. Используя шаблон репозитория, я только смоделировал следующие два интерфейса:

interface IGroupRepository
{
    Group FindById(int groupId);
}
interface IUserRepository
{
    User FindById(int userId);
    IQueryable<User> GetGroupMembers(int groupId);
    void AddUserToGroup(User user, Group group);
    void RemoveUserFromGroup(User user, Group group);
}

Почему-то это не так. Я хочу создать чистую модель предметной области, а не просто слой доступа к данным. Что было бы лучшим способом для моделирования выше?

РЕДАКТИРОВАТЬ: Кажется, что основной вопрос здесь заключается в том, можно ли с рекомендациями DDD рассматривать пользователя как «подобъект», в то время как в то же время он также является совокупным корнем? Как я понял, DDD утверждает, что совокупные корни должны извлекаться и храниться только из одного места (хранилища), поэтому я немного запутался.

Ответы [ 2 ]

3 голосов
/ 29 апреля 2009

Если вы используете ORM, такой как NHibernate, для его полного потенциала, вы можете использовать такие методы:

class Group
{
    List<User> members;

    void Join(User user)
    {
        members.Add(user);
    }

    void Leave(User user)
    {
        members.Remove(user);
    }
}

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

Это позволит упростить ваши интерфейсы до:

interface IGroupRepository
{
    Group FindById(int groupId);
}

interface IUserRepository
{
    User FindById(int userId);
}

Этот должен дать вам некоторые рекомендации по работе с NHibernate.

1 голос
/ 29 апреля 2009

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

public class User
{
    public virtual ICollection<Group> Groups {get;set;}
}
...