DDD限界上下文(Tasks与Meetings)间的依赖建模疑问
限界上下文建模疑问:Task与Meeting的状态、关联及集成问题
场景概述
存在名为tasks的限界上下文(BC),包含Task聚合根;还有名为meetings的BC,包含Meeting聚合根。代码示例如下:
// 在BC "tasks"中 class Task extends AggregateRoot { private TaskId taskId private string name private string description ... static func register(TaskId taskId, ...): Task { ... } func rename(string newName) { ... } ... } // 在BC "meetings"中 class Meeting extends AggregateRoot { private MeetingId meetingId private DateTime meetingDate ... static func plan(MeetingId meetingId, ...): Meeting { ... } func postpone(DateTime newMeetingDate): void { ... } func scheduleTask(TaskId taskId): void { ... } ... }
业务规则
将Task安排至Meeting中讨论需遵循以下规则:
- 创建Task的人必须明确将其标记为“ready for meeting”,因为任务创建流程可能较长,Task可能处于“未完成”状态(如未添加文档、描述不清晰等);
- 一个Task只能被安排至一个Meeting,会议结束后必须对该Task给出Opinion(如“有效”“无效”“可行但需修改”等);
- 需提供API获取所有符合下一次Meeting安排条件的Task(即非草稿且未被其他Meeting安排)。
当前尝试的建模方案
我尝试在Task中添加status属性,初始值为“draft”,可通过特定操作改为“ready for meeting”:
class Task extends AggregateRoot { ... private Status status = Status.draft ... func markAsReadyForMeeting(): void { // 暂忽略其他检查、领域事件发布等逻辑 this.status = Status.readyForMeeting } ... }
但此时产生以下疑问:
- 如何创建查询API,且该API应归属哪个BC?因为Task的可用信息一部分在
tasksBC(是否为草稿?),另一部分在meetingsBC(是否已被安排至其他Meeting?); - 如何避免Task与Meeting间形成双向关联?Meeting需持有TaskId列表,但如果在Task的Status中添加
scheduled(MeetingId),会出现需同步的重复信息; - Opinion是在Meeting场景下给出的,但应保存在Task中,该如何处理?
另一种考虑的方案
我还考虑过在meetings BC中建立简化的Task模型,在其中管理状态而非在tasks BC中。此时tasks BC中无Status或Opinion,“标记Task为可用于会议”的操作将在meetings BC中实现。
我感觉这种方法更优,因为meetings BC可独立运行,但这样两个BC间会存在大量数据重复(均持有完整Task列表,仅包含信息不同)。
困惑与求助
我的建模是否有误?是否遗漏了要点?或者两个BC间应存在更多集成?
最后说明:两个BC实际比简化示例更复杂,包含更多组件,我认为应保持两者分离,但也愿意探索重构方案。
内容的提问来源于stack exchange,提问作者technicated
相关产品推荐
相关产品推荐

