You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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
  }

  ...
}

但此时产生以下疑问:

  1. 如何创建查询API,且该API应归属哪个BC?因为Task的可用信息一部分在tasks BC(是否为草稿?),另一部分在meetings BC(是否已被安排至其他Meeting?);
  2. 如何避免Task与Meeting间形成双向关联?Meeting需持有TaskId列表,但如果在Task的Status中添加scheduled(MeetingId),会出现需同步的重复信息;
  3. Opinion是在Meeting场景下给出的,但应保存在Task中,该如何处理?

另一种考虑的方案

我还考虑过在meetings BC中建立简化的Task模型,在其中管理状态而非在tasks BC中。此时tasks BC中无Status或Opinion,“标记Task为可用于会议”的操作将在meetings BC中实现。

我感觉这种方法更优,因为meetings BC可独立运行,但这样两个BC间会存在大量数据重复(均持有完整Task列表,仅包含信息不同)。

困惑与求助

我的建模是否有误?是否遗漏了要点?或者两个BC间应存在更多集成?

最后说明:两个BC实际比简化示例更复杂,包含更多组件,我认为应保持两者分离,但也愿意探索重构方案。


内容的提问来源于stack exchange,提问作者technicated

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 08:25:21