DDD战术设计:课程预约系统聚合根是否过多?
DDD聚合根简化优化建议
核心判断原则
聚合根的设立核心是维护业务一致性边界,仅当对象需要独立生命周期、全局唯一标识、跨边界独立交互时,才需要设为聚合根。基于你的业务场景,现有聚合根可按以下方向简化:
1. 降级Teachers为聚合内实体/值对象
如果Teacher仅作为课程/私教课的关联角色,没有独立的业务生命周期(比如不需要单独创建、删除Teacher而不影响关联课程的正常运作),无需将其设为聚合根:
- 若Teacher仅需存储姓名、工号等基础信息,可作为值对象嵌入到Courses或PrivateLesson聚合中;
- 若Teacher需要维护排班、资质等关联信息,可作为聚合内的实体,由课程聚合根统一管理其与课程的绑定关系。
- 仅当Teacher需要独立管理(比如单独维护师资档案、跨课程排班规则等独立业务)时,才保留为聚合根。
2. 调整Items的聚合边界
附加商品的核心是与课程的关联规则(集体课专属列表、私教课固定列表),可分两种情况处理:
- 无需全局商品管理:如果商品不需要独立上架/下架、库存管理等全局业务,直接将允许的商品列表作为值对象集合(存储商品名称、价格等信息)嵌入到Courses和PrivateLesson聚合中,无需单独设为聚合根;
- 需要全局商品管理:如果商品有全局统一的生命周期管理需求,保留Items为聚合根,但在课程聚合中仅存储商品ID,预约时通过领域服务校验商品是否在允许列表内。
3. 合并PrivateLessonsPricelist到PrivateLesson聚合
私教课价目表是随年度时段、时段变化的定价规则,本质是私教课业务的核心组成部分,无需单独设为聚合根:
- 将PrivateLessonsPricelist拆分为聚合内的PricelistEntry实体集合,按年度时段划分定价规则;
- 设立PrivateLesson聚合根,统一管理私教课的定价规则、固定附加商品列表、关联师资等信息,确保定价调整与私教课业务的一致性。
4. 保留Courses聚合根并优化内部结构
集体课本身是独立的业务实体(有独立排期、报名规则、价目表),保留Courses作为聚合根是合理的,但可优化内部结构:
- 将集体课的独立价目表设为聚合内的实体;
- 将专属允许商品列表设为聚合内的值对象集合或关联Items ID列表;
- 关联的Teacher作为聚合内的实体/值对象,无需独立聚合根。
简化后建议的聚合根清单
- Courses:包含集体课基础信息、独立价目表实体、专属附加商品列表、关联师资信息
- PrivateLesson:包含私教课定价规则集合、固定附加商品列表、关联师资信息
- Items(可选):仅当需要全局商品生命周期管理时保留
关键注意点
- 聚合根的拆分不是越少越好,核心是确保同一聚合内的操作必须强一致(比如创建集体课时必须同时确认价目表和允许商品),跨聚合的操作通过领域服务协调;
- 避免过度拆分导致的分布式事务复杂度,聚合内的操作可通过本地事务保证一致性。
内容的提问来源于stack exchange,提问作者Kiske1
相关产品推荐
相关产品推荐

