说到DDD领域驱动设计,都有点蹭热点的感觉。这几年后端圈子逢人必提架构,提架构必提DDD,感觉DDD的中文翻译不像是“领域驱动设计”而是“对对对”,但是笔者作为一名研发大头兵在写代码的时候经常有种感觉“道理我都懂,但是我还是迷糊”的感觉,总是深感落地困难,在经历了多个DDD项目落地实践之后,笔者总结一下作为一名一线研发对领域驱动的理解,希望对各位有所帮助,此外领域驱动设计的实现并非是一套通用的准则,不同项目可能在具体落地方面略微有所变化,本文只是尽量归纳共性
搭建一个DDD项目,在最开始就要定义好各个模块的职责和POM依赖关系,笔者所在公司一般利用alibaba-Cola的maven骨架快速创建DDD项目结构,cola官网给出了两张图,可以作为一般DDD项目的分层指南:


下面我将对上图中的每一层进行详细解释,以及我们在日常开发的时候应该把什么样的代码放到这一层里面。
领域驱动设计,从名字来看最重要的就是领域,领域,在我看来就是边界。在早期做小项目的时候,建包的时候往往建一个叫做entities的包,这个包里面放的是都是一些对象,这些对象有两个特点:
(1)类除了属性就是get/set,都是简单类 (2)这个包或者模块下面只会有常量或者简单类,不会存放接口,这个包或者模块里面完全没有“行为”
但是如果仔细想想这个分包存在不合理之处。不合理之处在于贫血模型过多,大量的类只有属性没有行为,这个分包就是一个存放简单类的大集合,这种不合理之处在于和面向对象设计的思路相悖。
总的来说在DDD的设计理论下,这一层是毫无疑问最重要的一层,领域划分有一整套的方法论,领域划分的好不好直接决定了后期系统的可维护性高不高,这里笔者看了很多讲解DDD领域划分的文章,给我的感觉是看起来很有用,名词都很高端,但是实际还是用不好,笔者认为领域建模是需要大量训练的,不是说了解了几个名词例如“事件风暴”、“故事地图”,“用例分析”,“从战略到战术”就自然成为领域大师了的。
概括的说这一层包含下述要素:

具体来说这一层适合承载下述内容:
事件:领域内部发生了某些事件,需要对相关的领域进行事件传播,传播的就是事件,比如一个下单动作,就会发送一个下单事件,告知仓储领域锁定库存,所以需要定义一些事件对象。
实体和值对象:
值对象: 值对象用于描述领域里某个方面而本身没有概念标识(无ID)的对象。值对象 不可变性:值对象一旦创建完成后就不可以修改;唯一方法是重新创建一个对象(所以值对象咱们不需要定义set方法)
可替换性: 属性相同的两个值对象是完全等价的,在使用是可相互替换
实体: 实体是重要的领域概念,实体的3个主要特征: ID: 唯一的身份标识。 ID相同代表实体是同一个 Lifecycle: 实体的生命周期具有连续性 Status: 生命期经历不同的状态(例如常见的订单状态)
聚合:一般由多个实体和值对象组成,具备行为
工厂:一个聚合体内部有多个实体和值对象这样的话创建聚合体就需要一个工厂方法来简化复杂的创建过程。