本文作者是组内同事 杜宁,目前负责美团外卖活动管理模块业务。
什么是领域驱动模型?
2004年Eric Evans 发表《领域驱动设计——软件核心复杂性应对之道》(Domain-Driven Design –Tackling Complexity in the Heart of Software),简称Evans DDD,领域驱动设计思想进入软件开发者的视野。领域驱动设计分为两个阶段:
1、以一种领域专家、设计人员、开发人员都能理解的通用语言作为相互交流的工具,在交流的过程中发现领域概念,然后将这些概念设计成一个领域模型;
2、由领域模型驱动软件设计,用代码来实现该领域模型;
简单地说,软件开发不是一蹴而就的事情,我们不可能在不了解产品(或行业领域)的前提下进行软件开发,在开发前,通常需要进行大量的业务知识梳理,而后到达软件设计的层面,最后才是开发。而在业务知识梳理的过程中,我们必然会形成某个领域知识,根据领域知识来一步步驱动软件设计,就是领域驱动设计的基本概念。而领域驱动设计的核心就在于建立正确的领域驱动模型。
传统软件开发与贫血模型
传统的开发思想
传统开发四层架构
在传统模型中,对象是数据的载体,只有简单的getter/setter方法,没有行为。以数据为中心,以数据库ER设计作驱动。分层架构在这种开发模式下,可以理解为是对数据移动、处理和实现的过程。
以商家活动为例,首先设计数据库表配置
设计WmActPoi对象,只有简单的get和set属性方法
public class WmActPoi {
private Long id;
private String wmPoiId;
private Integer startTime;
private Integer endTime;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Integer getWmPoiId() {
return wmPoiId;
}
public WmActPoiDB setWmPoiId(Integer wmPoiId) {
this.wmPoiId = wmPoiId;
}
......
}
````
Service层代码实现
<div class="se-preview-section-delimiter"></div>
class WmActPoiService {
saveWmActPoi(); //保存活动
checkWmActPoi(); //活动校验
….
}
class WmActPoiQueryService {
queryWmActPoi(); //查询活动
queryWmActPoiByWmPoiId(); //根据门店查询活动
….
}
可以看到,业务逻辑都是写在Service中的,WmActPoi充其量只是个数据载体,没有任何行为,是一种贫血模型。**简单的业务系统采用这种贫血模型和过程化设计是没有问题的,**但在业务逻辑复杂了,业务逻辑、状态会散落到在大量方法中,原本的代码意图会渐渐不明确,**我们将这种情况称为由贫血症引起的失忆症**。
![image.png](https://upload-images.jianshu.io/upload_images/5401760-dca70a6662cc6ea3.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
传统架构的特点: