不少小伙伴在实践DDD领域驱动设计的时候,应该都有纠结过项目的结构应该如何设计。
经过实践,本人总结了一个比较实用的项目结构。今天就跟大家分享一下。

本文适合读者:

  1. 了解DDD领域驱动设计概念;
  2. DDD领域驱动设计实践中遇到难题;

1. 项目结构模块依赖关系:

模块依赖图:

项目的结构主要分为5个模块:
其中 用户接口层,应用层,领域层和基础设施层 的作用在这里就不做过多介绍了,通用工具层指的是自己团队的通用工具,是一些技术性的工具,不能包含有业务相关实现的工具类,但是,如果你的项目在开发过程中也需要编写一些技术通用的工具,那么就可以自己创建一个通用工具层。

2. 依赖关系介绍

从图中可以看出,用户接口层依赖应用层,应用层依赖领域层和基础设施层,领域层只依赖通用工具。

基础设施层比较特殊,除了依赖通用工具,还会依赖领域层。这个关系就是核心所在,领域层中只编写业务相关的代码逻辑,不包含任何的技术性的实现,当需要存储或者调用其他服务时,都是通过接口调用,而接口的实现在基础设置层,所以是基础设施层依赖领域层。这种依赖关系叫做依赖倒置

举个例子:
当一个订单领域在执行业务行为的过程中,需要获取历史订单数据,这个时候,通过调用 OrderRepository 接口的某个方法来获取的。而 OrderRepositoryImpl 接口的实现类实际在基础设施层。对于领域层来说,并不需要关心这些数据是怎么来的。

同时依赖基础设施层的还有应用层,如果说在实际的开发过程中,想要实现的功能只是简单的CRUD,那么完全可以直接调用基础设施层的数据存储实现,不需要经过领域层。如果只是为了依照规则通过领域层再去调用基础设施层,那这样就完全可以称为是过度设计,其实大可不必。

3. 实现示例

1 用包划分

2 使用Maven子模块划分

无论通过包划分还是Maven模块划分,从逻辑上讲都可以实现。但是这两种实现方式有一个区别,就是约束性的强弱不同。

通过包划分,虽然可以跟团队成员口头描述每个包之间的依赖关系,但是这个需要依靠每个开发者自己控制,如果开发者想要在领域层编写一些技术实现的代码,依然是可以的。

但是如果是Maven模块进行划分,就能在代码上进行约束了,领域层并没有依赖基础设施层,所以无法实现数据存储和查询等技术。