聚合根引用聚合根的集合

问题描述 投票:0回答:1

我一直在学习 DDD,只是想确保我理解正确。我在不同的地方读到,聚合根属性不应直接引用其他聚合根中的实体。假设我们有 2 个聚合根:Student 和 Course。

最初,我会这样设计我的模型:

public class Student
{
    private int Id {get;}
    private readonly List<Course> _courses = new();
    public IReadOnlyCollection<Course> Courses => _courses;

    public void Enroll(Course course)
    {
        _courses.Add(course);
    }
}
public class Course
{
    private int Id {get;}
    private readonly List<Student> _students = new();
    public IReadOnlyCollection<Student> Students => _students;

    public void AddStudent(Student student)
    {
        _students.Add(student);
    }
}

在了解了不引用其他聚合中的实体后,我最终得到了 id 集合:

public class Student
{
   private int Id {get;}
   private readonly List<int> _courses = new();
   public IReadOnlyCollection<int> Courses => _courses;

   public void Enroll(Course course)
   {
       _courses.Add(course.Id);
   }
}

这是正确的吗?感觉有点奇怪而且违反直觉。我也不喜欢现在没有类型保证我的集合元素将是预期的类型。我可能会错误地更改代码来执行

_students.Add(course.Id)
操作,并且该错误很难发现。有什么建议可以避免这种情况吗?

c# aggregate domain-driven-design aggregateroot
1个回答
0
投票

我也不喜欢现在没有类型保证我的集合元素将是预期的类型。

这里的标准答案:将实体标识符本身建模为类型 - 又名“值对象”。

public class StudentId {
  // ...
}

public class Student {
  StudentId id;
  // ...
}

TADA - 你又拥有类型安全了。作为额外的好处,值对象还减少了直接耦合到内存表示的代码量,从而减少了您以后发现标识符应该是字符串时需要执行的工作量。

请参阅领域驱动设计(Evans,2003)第 5 章。


正确吗?

也许?

通常情况下,“关系集合”将被建模为标识符集合,期望您在创建报告时可以将所有内容连接在一起。

这是否意味着我们应该在 Student 中拥有课程标识符的集合?或者课程中学生标识符的集合?或者是其他东西?上述任何一种都是可能的,具体取决于您试图满足的需求。

© www.soinside.com 2019 - 2024. All rights reserved.