【问题标题】:DDD: How should adding and removing related entities be modelled?DDD:添加和删除相关实体应该如何建模?
【发布时间】:2009-04-29 16:34:48
【问题描述】:

假设我们在域模型中有两个聚合根:组和用户。

现在,可以将用户添加到组或从组中删除。使用存储库模式,到目前为止我只建模了以下两个接口:

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 的指导方针是否可以将 User 视为“子对象”,同时它也是聚合根?据我了解 DDD,它指出聚合根只能从一个地方(存储库)检索和存储,所以这就是我有点困惑的原因。

【问题讨论】:

    标签: c# design-patterns domain-driven-design


    【解决方案1】:

    如果您使用像 NHibernate 这样的 ORM 来充分发挥它的潜力,您可以使用如下方法:

    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);
    }
    

    This 应该会给您一些关于使用 NHibernate 执行此操作的指导。

    【讨论】:

    • NHibernate 信息现在可以在 nhforge.org 找到 - 旧网站已经关闭了一段时间
    • 这种方法不是将 User 视为不是聚合根吗?顺便说一句,我很困惑,我还不关心持久性 - 只是在寻找一般的设计模式
    • 有点。如果您只考虑这种情况,那么它可能不是聚合根。但是,我假设您会使用 User 更多。拥有存储库的唯一原因是(主要)作为一种持久化方式。所以想象一下,如果没有存储库,您将如何对其进行建模。
    【解决方案2】:

    在这种情况下,我会考虑在用户上创建一组组,反之亦然。这样您就不需要在存储库上使用专门的方法。大多数 ORM 框架都支持这种映射

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

    【讨论】:

    • 核心问题似乎是如果它打破了域模型的一致性,将用户视为“子对象”,而实际上它是一个聚合根。稍微修改一下问题
    • 在仔细考虑之后,在组上拥有用户集合似乎很自然。它可能只是被视为对聚合根实例的引用列表
    猜你喜欢
    • 1970-01-01
    • 2023-04-03
    • 2021-11-20
    • 1970-01-01
    • 1970-01-01
    • 2012-07-30
    • 1970-01-01
    • 1970-01-01
    • 2012-01-14
    相关资源
    最近更新 更多