DDD
Tackling Complex Problem
Netease - Jiang Wenkang
What's DDD?
DDD是一种应对复杂需要的软件开发方法,通过核心业务模型的不断演化来实现。
Why DDD?
三段式开发流程的弊端
- 无法复用
- 后期维护成本高
- 业务部门和开发人员沟通成本高
表现特征
- 贫血模型
- Fat Service
- 过程化的开发方式
Why DDD?
DDD带来的好处
表现特征
- 富领域模型
- 易于测试
- 面向对象的开发方式
- 代码复用
- 高度模块化、易扩展
- 业务团队和开发人员沟通成本降低
开发模式的比较
DDD的应用场景
- 你有一个相对固定的业务场景
- 你有一个相对复杂的问题领域
如何实施DDD?
- 战略
- 战术
向领域专家取经-DDD战略
- 每个行业都有领域专家
- 每行代码都有其业务价值
How ?
- 把开发人员和领域专家聚集在一起
- 了解业务战略
形成通用语言-DDD战略
- 产品经理说的是A,我理解的是B,运营觉得是C,测试觉得是D?
How ?
- 项目的所有参与者都要参与领域建模
- 讨论过程中的“术语”沉淀并文档化
- 实时咨询和反馈
找到核心领域-DDD战略
- 任何业务都有一个核心领域
- 识别并且找到这个核心领域对项目的成功是至关重要的
- 对核心领域的投入会增加业务的竞争力
举个例子:
1.访问控制系统的核心是权限
2.仓库系统的核心是库存
找到核心领域-DDD战略
DDD战术模型
-
实体
-
值对象
-
聚合
-
领域事件
-
领域服务
...
实体-DDD战术
- 实体应该包含数据和行为,而不仅仅是geter和setter
- 实体的行为应该反映业务逻辑
- 实体的行为应该小而美
- 实体要尽量避免依赖其他实体
- 实体的行为应该是仅对本实体属性的操作
- 实体都有一个唯一标识符
- 实体是可变的
值对象-DDD战略
- 不变形
特点
- 描述或者度量某个事物
- 可被替换和比较
好处
- 方便创建、测试和维护
- 更加准确的表述了事物的特点
- 类型安全和提前检查
public class OldPushService {
public void push(String message, long phone) {
//检查phone的合法性
Op op = check(phone);
if (op == Op.Mobile) {
//发送到移动网关
} else if (op == Op.Union) {
//发送到联通的网关
}else{
//error
}
}
Op check(long phone) {
if (phone / 100000000 == 184) {
return Op.Mobile;
}
if (phone / 100000000 == 133) {
return Op.Union;
}
return Op.UNKNOWN;
}
enum Op {
Mobile,
Union,
UNKNOWN
}
}
public class NewPushService {
public void push(String message, PhoneNumber phoneNumber) {
if (phoneNumber.isMobile()) {
//发送到移动网关
} else if (phoneNumber.isUnion()) {
//发送到联通的网关
} else {
//error
}
}
}
public class PhoneNumber implements ValueObject<PhoneNumber> {
private long code;
public PhoneNumber(long code) {
//验证号码的合法性
this.code = code;
}
//是否为中国移动号码
public boolean isMobile() {
return code / 1000000000 == 184;
}
//是否为中国联通号码
public boolean isUnion() {
return code / 1000000000 == 133;
}
public long code() {
return this.code;
}
@Override
public boolean isSame(PhoneNumber other) {
return other != null && code == other.code;
}
}
聚合-DDD战术
- 聚合内保证业务的一致性(强一致)
- 聚合应当设计的小巧,正好表示一个业务对象的最小集合
- 聚合间保持最终一致就行(弱一致)
领域事件-DDD战术
- 领域事件用于记录领域中发生的事情(动作+上下文)
- 领域事件发布形式类似于Observer模式
- 领域事件从本地发布,可以只在本地传播,也可以发布到远端系统(一般使用MQ中间件)
领域事件-DDD战术
领域服务-DDD战术
- 不适合放到领域或者值对象中的服务
- 包含业务逻辑
- 是领域模型的一部分
- 与应用服务是不同的
注意!
- 滥用会导致领域贫血
架构
六边形架构
SOA
REST
- REST是一种架构风格,以资源为中心
- REST定义了与资源交互的方式
- DDD可以以REST的风格来暴露领域对象,不是直接暴露
落地
展望
DDD展望
- 与微服务相得益彰
- 与敏捷开发的关系
- 在传统企业中的应用
实施DDD的难点
- 前期投入相对比较大
- 要求参与项目的每个人都了解领域
- 公司或者领导层面的支持
- 门槛相对较高,依赖开发人员的经验
DDD书籍推荐
Thanks
Q & A
DDD-Tackling Complex Problem
By 蒋文康
DDD-Tackling Complex Problem
From netease Michael Jiang's share
- 1,567