前言
做在线教育 SaaS 的这些年,我最常被产品同事问到一个问题:“这个功能应该放在哪个服务里?”
听到这个问题的时候,我一般不会直接回答“放在哪个服务”,而是会反问一句:“这个功能到底属于哪个领域?”
领域没分清,服务的边界就是一笔糊涂账。今天我想用一套相对系统的视角,把这件事从头讲清楚。
一、传统做法为什么会失效
过去做企业系统,我们习惯怎么开始?拿到需求,先画几张表,列出 user、order、course 这些字段,然后从 Controller 一路写到 Dao。这种“数据库先行”的思路在单体时代问题不大,因为一个系统就一个进程、一套表,边界由物理进程天然划定。
但当业务开始膨胀——比如在线教育平台从“卖课”延伸到“直播课、训练营、企业内训、证书、就业服务”——就会出现这些问题:
- 表越来越多,单库撑不住。
- 不同业务写同一张表,字段互相污染。
- 想要把一个能力单独抽出来变成公共服务,改动面巨大。
- 微服务拆了,但拆出来的服务彼此重叠,拆完反而更乱。
根本原因只有一个:我们在拆服务之前,没有先把“领域”这件事想清楚。
二、领域设计到底在解决什么问题
领域设计的核心目标,是先在业务侧把边界划清楚,再让代码跟着边界走。
这件事的逻辑其实非常朴素:
业务问题 → 拆分成多个子问题 → 每个子问题对应一个领域 →
在每个领域内建立模型 → 模型映射到代码 → 代码就是微服务
这样一来:
- 服务的边界来自业务边界,而不是来自某个人的“感觉”。
- 业务调整时,模型先行,代码跟着调整,改动是局部的。
- 不同领域之间的耦合度天然低,团队可以并行开发。
这个思路有一个专有名词,叫领域驱动设计(Domain-Driven Design,DDD)。
三、DDD 的两把刷子
DDD 不是一种框架,也不是一种技术,它是一套设计方法论,分两部分:
1. 战略设计:站在业务视角
解决“领域怎么切、边界在哪、术语怎么统一”的问题。这一步产出的不是代码,而是:
- 领域模型
- 限界上下文
- 通用语言
这些产物直接决定微服务应该怎么拆。
2. 战术设计:站在技术视角
解决“模型怎么变成代码、怎么落地”的问题。这一步涉及:
- 实体、值对象、聚合根
- 领域服务、应用服务
- 仓储(Repository)
战术设计是把战略设计画出的边界,真正落到代码上。
四、DDD 和微服务到底是什么关系
| 视角 | DDD 关注什么 | 微服务关注什么 |
|---|---|---|
| 业务 | 领域边界、通用语言 | — |
| 架构 | — | 进程间通信、容错、隔离 |
| 组织 | 团队与领域专家协作 | 独立开发、测试、部署 |
| 演进 | 领域模型随业务演进 | 架构随流量演进 |
一句话总结:DDD 是微服务拆分的“理论依据”,微服务是 DDD 的“物理实现”。两者的内核完全一致——用边界来对抗复杂度。
五、我用 DDD 重构在线教育平台的真实感受
我们做在线教育 SaaS 的时候,最早是一套单体。课程、订单、直播、证书、IM 全堆在一起。后来业务一复杂,每次发版都像拆炸弹。
转 DDD 之后,我做了三件事:
- 做了一次领域梳理,把整个业务分成:课程域、报名域、学习域、教学域、证书域、内容域、运营域。
- 为每个域建立通用语言,确保产品、运营、技术说的是一回事。
- 按限界上下文拆微服务,每个微服务对应一个上下文,独立部署。
结果:
- 发版频率从两周一次变成一天多次。
- 新业务接入速度大幅提升。
- 团队按领域划分,沟通成本明显下降。
最大的感受是:DDD 不是让你设计更复杂,而是让你“复杂的部分”和“简单的部分”清晰分开。
六、这一系列我会讲什么
我打算用一个在线教育 SaaS 的完整例子,把 DDD 的核心概念全部串一遍:
- 领域、子域、核心域、通用域、支撑域
- 限界上下文与通用语言
- 实体、值对象、聚合、聚合根
- 领域事件
- DDD 分层架构 + 整洁架构 + 六边形架构
- DDD、中台、微服务的协作
适合人群:做复杂业务系统的架构师、后端开发、技术负责人。
总结
DDD 不是银弹,但它给了一个可复用的方法来处理复杂业务系统的设计问题。比起“拍脑袋拆服务”,它最大的价值是让设计过程本身可被讨论、可被复盘、可被传承。
下一篇我们进入领域与子域——把“业务边界”这件事,从概念讲到实操。