【发布时间】:2011-02-01 06:21:21
【问题描述】:
我不确定如何模拟这种关系...
一个教室有很多座位,每个学生都在一个教室里学习,里面有一个最喜欢的座位。
在我看来,我有两个聚合根:教室和学生,座位 a 是由教室聚合的实体...
对于一个学生有一个最喜欢的座位,它必须持有对它的引用(座位不是聚合根)。
有什么建议吗? 提前致谢,埃里克。
【问题讨论】:
标签: domain-driven-design modeling
我不确定如何模拟这种关系...
一个教室有很多座位,每个学生都在一个教室里学习,里面有一个最喜欢的座位。
在我看来,我有两个聚合根:教室和学生,座位 a 是由教室聚合的实体...
对于一个学生有一个最喜欢的座位,它必须持有对它的引用(座位不是聚合根)。
有什么建议吗? 提前致谢,埃里克。
【问题讨论】:
标签: domain-driven-design modeling
嗯,这取决于...我可能会有像你这样的座位的教室集合。学生可以是实体,但座位对我来说更像是价值对象。但是,这一切都取决于您的上下文。我不确定什么对你很重要,如果我的建议没有意义,请解释你的上下文。
【讨论】:
一个可能的选项是每个座位都有一个该座位最喜欢的学生列表。教室聚合根将负责维持学生在教室中不能拥有多个最喜欢的座位的约束。使用此选项,座位是由教室聚合的实体(不是值对象),并引用学生。
【讨论】:
听起来您需要引入一个值对象Location,它描述了教室中的一个地点,然后您可以在学生班中像这样对它们进行建模:
public IDictionary<Classroom, Location> FavoriteSeats;
教室可以通过位置引用Seat 实体。
(如果它们真的是实体首先 - 您甚至可能会发现您不需要将座椅建模为实体(例如,“闻起来像汉堡包的蓝色塑料椅子)。 )
【讨论】:
手术后几个月,但以防万一。
@Jeff Sternal 走在正确的轨道上。问题从根本上是关于管理学生、教室和座位之间的三向(三元)关系。既然这是一个关系问题,让我们暂时保留关系概念并将其称为 FavouriteSeat(Student, Classroom, Seat)。
如上所述,除了唯一标识符之外,该问题不需要任何关于它们的任何知识。现在让我们使用伪类型“ID”(并不重要,只要每个都是唯一的)。
在伪sql中,我们有:
create table FavouriteSeat(
StudentID ID not null,
ClassroomID ID not null,
SeatID ID not null)
该表上的标准 CRUD(创建/读取/更新/删除)操作提供了所需的所有操作。但是,它缺少一些约束。现在,一个学生在教室里可能有 2 个或更多最喜欢的座位。尽管没有明确说明,但 OP 暗示学生在任何给定的教室中最多应该有一个(0 或 1)个最喜欢的座位。
我们可以通过在表上添加一个唯一键来解决这个问题。再次使用伪sql:
alter table FavouriteSeat add unique key (StudentID, ClassroomID)
现在,对于任何给定的教室,学生只能拥有一个最喜欢的座位。还有一个问题。该解决方案目前不支持定义哪些教室有哪些座位。我们可以通过以下方式解决:
添加一个列出每个教室中有效座位的新表格:
创建表 ClassroomSeat ( ClassroomID ID 不为空, SeatID ID 不为空)
alter table ClassroomSeat 添加唯一键(ClassroomID、SeatID)
向 FavouriteSeat 表添加外键,使其只能引用有效的 ClassroomSeats:
alter table FavouriteSeat add Foreign Key FK_Seat(ClassroomID, SeatID references FavouriteSeat(ClassroomID, SeatID)。
就是这样。 2 个关系、3 个键和标准 CRUD 操作涵盖了所述的所有要求。
关系模型可以很容易地转换为 OO/DDD。它需要一个用于 FavouriteSeat 和 ClassroomSeat 的实体以及用于 CRUD 操作的方法。这些方法必须强制执行上面的唯一和外键约束。
为了满足所述要求,Customer、Classroom 和 Seat 可以是值类型(尽管可能有更广泛的未说明的要求可能会改变这种情况)。无论哪种方式,他们都需要一个可以在 FavouriteSeat 方法中检查的唯一标识符属性。
【讨论】: