DDD领域驱动模型设计

时间:2022-08-31 12:49:30

背景

使用DDD开发大概也有五个月的时间了,由于当时公司导师的推荐,第一次接触DDD领域驱动到现在彻底迷恋这种开发的模式,为其思想的奥妙所折服,一直以来,总想花一点时间来总结一下,正直光棍节(天猫狂欢购物节)当天,“静下心来”(PS:没有人民币)总结一下。

说起DDD不得不说一篇文章:http://www.cnblogs.com/netfocus/archive/2011/10/10/2204949.html

第一次接触,就是这篇文章,当时看起来晦涩难懂,后来慢慢的读起来,每一次都有精神的提升,网上也有很多关于DDD的介绍,这里将不会在介绍概念什么的,下边主要是自己工作过程中的一些总结。

如何快速入门

第一次接触DDD的时候,概念高深莫测,奥秘深不可见,大有不知所云的趋势,后来导师的引导,让直接从项目中直接入手,遂逐步揭开其一层层雾纱,如图1:

DDD领域驱动模型设计

DDD一般的分层结构和调用顺序如上所述,infrastructure是基础设施层,domain是领域层,application是应用层,facade和facade-impl是门面层(前者是门面接口层,后者是门面实现层),webapp是用户接口层(采用web形式)。

下边是一种项目的分层图,采用的Maven管理代码。图2:

DDD领域驱动模型设计

分层的介绍

1、web:首先包含网站前端,如果使用SpringMVC的话,还需要其Controler,

DDD领域驱动模型设计

该Controler层主要是用于接收HTTP请求和返回客户端,一般不进行逻辑上的判断,其代表了用户可以进行的操作,一般不涉及领域驱动的思想,示例代码:

@ResponseBody
@RequestMapping(value = "/create", method = RequestMethod.POST)
public String create(AirlineWhiteListDTO airlineWhiteListDTO) {
MDC.put(ConstString.TRACE_ID, LogUtil.getTraceId(ConstAirlineWhiteList.CREATE));
Response response = airlineWhiteListFacade.create(airlineWhiteListDTO);
return super.handleResponse(response);
}

第一行使用MDC用于记录(打log)http请求的顺序和调用的方法,第二行调用“门面层”facede,获得Response返回对象,第三行用于判断是返回界面还是返回data等操作,即时SpringMVC的ModalAndView;

2、facade和facade-impl一个是门面层接口一个是门面层接口的实现类,示例代码:

@Autowired
IAirlineWhiteListApplication airlineWhiteListApplication;

public Response create(AirlineWhiteListDTO airlineWhiteListDTO) {
Response response = new Response();
try {
AirlineWhiteList airlineWhiteList = AirlineWhiteListAssembler.toEntity(airlineWhiteListDTO);
airlineWhiteListApplication.create(airlineWhiteList);
} catch (Exception e) {
response = new Response(e);
}
return response;
}

可以看出这是在web的controller中访问的方法,主要进行数据的组装(实体对象和数据传输对象的转换),以及返回对象Response的转换。

之所以成为门面层,我们暂可认为是我们用户可以看到的整个系统的东西,例如上述中的Response就是返回给用户看的东西。

3、Application层,上述的facade调用到了application中的方法,

@Inject
private AirlineWhiteList airlineWhiteList;

public boolean create(AirlineWhiteList airlineWhiteList) {
return this.airlineWhiteList.add(airlineWhiteList);
}

这一层主要是操作实体对象的,是于数据更近一层的操作,主要定义了用户所拥有的方法和属性,操作实体对象层,将实体对象所有的方法展示出来供用户使用;

4、domain层,数据实体层,相比MVC中的modal简单的只是数据库的映射,这种“毫无灵魂”的对象,领域模型中不但有一个实体对象的属性还有其方法,(我们可以在实际使用的时候使用继承DTO的方式),在这一层中定义了实体对象操作数据库的方法;

这里我们的实体对象不仅是拥有属性还具有方法的,就像一个人一样,我们不但拥有做人的基本特征(两手、两脚等),我们还有属于自己的技能(方法),这样的话才是一个拥有灵魂的东西;

5、infra这一层包含了访问数据库的方法、数据仓储(sql、nosql、api)和一些工具类,service等;

由于是domain层调用该层的,实体对象的操作固然包含CRUD,既是我们需要进行对数据库的操作,当我们只有一个数据源的时候,很简单,但是后期项目中数据源可能会增加,可能会添加缓存等,这样的话使用原来的MVC模式的话,我们可能需要修改很多,如下图:

DDD领域驱动模型设计

但是使用DDD的话,由于我们的Domain调用的是infra 数据仓库Repository接口,Repository中定义了访问数据源的方法,这样的话,当我门新增数据源的时候,我们的Domain层以上都无需修改,只需进行infra层的修改即可。
DDD领域驱动模型设计

上图中有2个数据源,一个是sql一个是nosql,在方框中的Repository即调用的是nosql和sql中的方法,这样的话Domain直接调用Repository即可。

领域驱动的示例:

如果想快速的领回DDD的奥妙,这里有一个案例,一个很不错的开源系统,使用的正是DDD思想,可以把代码下载下来仔细研究,其中的思想是很不错、很不错的,地址如下:http://www.openkoala.org/

总结:

类比MVC“哑铃式”的分层结构中,Model和View代码少,Controller代码臃肿的布局格式,DDD拥有更多的分层,各层之间各司其职,协调工作,一步步调用,井然有序,对于后期的维护,只要是熟悉DDD的开发人员都可以很好的维护。