【发布时间】:2019-05-29 13:13:39
【问题描述】:
DDD 新手我有一个简单的案例,我想使用 DDD 方法进行建模
2 个实体 Student 和 Course
Student 的相关属性是 StudentId 和 Budget
Course 的相关属性是 CourseId 和 Price
Student 和 Course 是可以独立存在并拥有自己生命周期的实体
业务要求:
1) 学生可以预订一门课程(CourseId 是学生表的 fk)
2) 只有当用户的预算高于或等于课程价格时,学生才能预订课程。
3) 课程价格的变化不影响已预订课程的学生。
4)当学生预订课程时,他的预算保持不变(可能会在课程结束后更改)
5) 可以修改学生预算设置不同的金额,但新金额必须高于或等于用户预订课程的价格。
设置较低的数量会引发运行时错误。
按照领域驱动设计对这个简单案例进行建模的方法是什么?在哪里执行这两条商业规则(第 2 点和第 5 点)?
由于课程可以在没有学生的情况下存在,所以我无法定义学生是根实体而课程是子实体的聚合。可以吗?
但与此同时,在第 5 点定义的业务规则在我看来似乎是一个不变量。是吗?
那么在哪里以及如何应用这些规则呢?
我尝试了一种服务方法,可以适用于第一个简单规则(第 2 点),但对于第 5 点描述的规则失败
var student = studentRepository.Get(srtudentId);
var course = courseRepository.Get(courseId)
var studentService = new StudentService();
studentService.SubScribeStudentToCourse(student, course);
studentRepository.Update(student);
StudentService.ChangeStudentBudget(student, 100000);
studentRepository.Update(student);
当我用新预算更新学生时,其他人可以更改课程价格,导致学生预算不一致
public class StudentService
{
SubScribeStudentToCourse(Studen student, Course course)
{
if (studentt.Budget >= course.Price)
{
student.CourseId = course.CourseId
}
}
ChangeStudentBudget( Student student, decimal budgetAmount)
{
if (student.CourseId != null)
{
var studentCourse = courseRepository.Get(student.CourseId);
if ( studentCourse.Price <= budgetAmount)
{
student.Budget = budgetAmount;
}
else
{
throw new Exception("Budget should be higher than studentCourse.Price");
}
}
}
}
【问题讨论】:
-
你试过什么?你的问题看起来像家庭作业
-
我正在接近 DDD,我正在想象一个假设的情况,就像描述的在哪里定义两个简单的业务规则(第一个可能是一个简单的验证规则,另一个是在任何时候都需要遵守的不变量)你改变 Student.Budget 的值
-
设置较低的数量会引发运行时错误。这就是问题#1。我稍后会跟进答案,但现在只想指出 SetAmount 是基于“Crud”的思想。你的学生应该有存款和取款方法。不是设置金额。实际的“SetAmount”逻辑将根据不变量封装在这些方法中。
标签: oop design-patterns architecture domain-driven-design