以在线考试系统项目为例,结合DDD(领域驱动设计)企业级规范工程和业务流程的设计指南。我会以DDD入门者为目标人群,通过这个在线考试系统,帮助你熟悉DDD的企业级开发流程、核心概念和代码规范。整个设计将分为以下几个部分:
- DDD 核心概念与在线考试系统的结合
- 战略设计:子域与限界上下文划分
- 战术设计:分层架构与领域模型
- 业务流程与领域事件驱动
- 企业级规范工程:代码结构、命名规范与团队协作
- 学习路径:从入门到实战的实践建议
一、DDD 核心概念与在线考试系统的结合
DDD 的核心是通过领域模型来表达业务逻辑,而不是通过技术实现来驱动设计。以下是与考试系统相关的核心概念:
| DDD 概念 | 在线考试系统中的体现 | 说明 |
|---|---|---|
| 领域 | 在线考试业务 | 系统要解决的核心问题空间,如考试管理、题库管理、成绩管理等 |
| 子域 | 核心子域:考试执行;支撑子域:用户管理;通用子域:通知服务 | 根据业务重要性划分 |
| 限界上下文 | 考试上下文、题库上下文、成绩上下文等 | 每个上下文有独立的领域模型和统一语言 |
| 实体 | 考生(ID唯一)、试卷(ID唯一) | 有唯一标识,状态可变 |
| 值对象 | 考试时长、题目分数 | 无唯一标识,不可变 |
| 聚合根 | 考试聚合根(包含题目、规则) | 保护聚合内的一致性 |
| 领域事件 | 考试开始事件、交卷事件 | 表示领域中发生的重要事情 |
二、战略设计:子域与限界上下文划分
战略设计是 DDD 的核心,用于界定业务边界和服务划分。以下是考试系统的子域和限界上下文划分示例:
1. 子域划分
- 核心子域:考试执行(组卷、考试过程、自动评卷)
- 支撑子域:用户管理、权限管理、成绩分析
- 通用子域:通知服务(邮件/短信)、文件上传(题目导入)
2. 限界上下文映射
| 限界上下文 | 职责 | 关联子域 |
|---|---|---|
| 考试上下文 | 考试生命周期管理(创建、开始、结束) | 核心子域 |
| 题库上下文 | 题目的增删改查、批量导入、分类 | 核心子域 |
| 成绩上下文 | 成绩计算、统计、发布 | 支撑子域 |
| 用户上下文 | 考生、教师、管理员的身份管理 | 支撑子域 |
3. 上下文映射图
考试上下文 ──→ 题库上下文(通过防腐层获取题目)
│
└─→ 成绩上下文(通过领域事件「考试完成」触发成绩计算)
💡 提示:限界上下文之间通过 防腐层 或 领域事件 解耦,避免直接依赖。
三、战术设计:分层架构与领域模型
针对考试系统,我们采用 DDD 经典四层架构(或六边形架构),确保领域层独立于技术和应用逻辑。
1. 分层架构
| 层级 | 职责 | 示例代码包结构 |
|---|---|---|
| 用户接口层 | 接收前端请求(Vue3),返回 DTO | exam-web/src/api/ |
| 应用层 | 协调领域对象,处理业务流程(如组卷用例) | exam-service/src/main/java/com/exam/application/ |
| 领域层 | 核心业务逻辑(实体、聚合根、领域服务) | exam-service/src/main/java/com/exam/domain/ |
| 基础设施层 | 数据库持久化、消息队列、外部 API | exam-service/src/main/java/com/exam/infrastructure/ |
2. 领域模型示例(考试聚合)
// 聚合根:考试
public class Exam implements AggregateRoot {
private ExamId id;
private String title;
private Duration duration;
private List<Question> questions; // 值对象列表
private ExamStatus status;
public void start() {
this.status = ExamStatus.IN_PROGRESS;
this.registerEvent(new ExamStartedEvent(this.id));
}
}
// 领域事件:考试开始
public class ExamStartedEvent implements DomainEvent {
private ExamId examId;
private Instant startedAt;
}
💡 提示:领域层不依赖任何外部框架,确保业务逻辑纯净。
四、业务流程与领域事件驱动
以下是一个核心业务流程的 DDD 实现示例:
业务流程:考生参加考试
- 考生进入考试(用户接口层接收请求)
- 应用服务协调:
- 调用领域服务验证考生权限
- 加载考试聚合根
- 触发
exam.start()
- 领域层逻辑:
- 考试聚合根检查状态是否可开始
- 发布
ExamStartedEvent
- 基础设施层:
- 将事件发送到消息队列(如 RabbitMQ)
- 成绩上下文订阅事件,初始化成绩记录
领域事件驱动架构图
考试上下文 → 发布「考试开始事件」 → 消息队列 → 成绩上下文订阅事件 → 生成成绩记录
五、企业级规范工程
1. 代码结构规范
exam-service/ # 后端服务
├── src/main/java/com/exam/
│ ├── application/ # 应用层
│ │ ├── ExamApplicationService.java
│ │ └── dto/ # DTO 类
│ ├── domain/ # 领域层
│ │ ├── model/ # 实体、值对象
│ │ ├── service/ # 领域服务
│ │ └── events/ # 领域事件
│ ├── infrastructure/ # 基础设施层
│ │ ├── persistence/ # 仓储实现
│ │ └── message/ # 消息发布
│ └── interfaces/ # 用户接口层
│ ├── web/ # REST 控制器
│ └── facade/ # 门面类
2. 命名规范
- 实体:
Exam、Question - 领域服务:
ExamGenerationService - 仓储接口:
ExamRepository - 领域事件:
ExamStartedEvent
3. 团队协作规范
- 统一语言:产品、开发、测试使用一致的术语(如“组卷”=“Exam Assembly”)
- 领域模型图:团队定期评审领域模型图,确保代码与设计一致
六、学习路径:从入门到实战
- 第一步:理解概念
- 阅读 DDD 核心概念(实体、值对象、聚合根)
- 在考试系统中识别这些概念(如“考生”是实体,“分数”是值对象)
- 第二步:划分限界上下文
- 根据业务功能划分考试系统的上下文(如考试、题库、成绩)
- 第三步:实现分层架构
- 按照四层架构搭建 SpringCloud 项目
- 第四步:领域事件驱动
- 使用 SpringCloud Stream 实现领域事件
- 第五步:团队协作
- 使用统一语言,定期评审领域模型
总结
通过以上设计,你可以将 DDD 的企业级规范应用到在线考试系统中。关键是:
- 战略设计划清业务边界,
- 战术设计保证代码结构清晰,
- 领域事件驱动业务流程解耦。
对于 DDD 入门者,建议从一个小上下文(如题库管理)开始实践,逐步扩展到整个系统。

1134

被折叠的 条评论
为什么被折叠?



