一篇带你快速入门DDD领域驱动设计
一、什么是领域驱动
领域驱动设计 Domain-Driven Design,简称DDD。软件对于行业并没有这么高的要求,他本身就是帮助其他行业更好的发展,赋能其他行业的。各个行业都有软件的身影,但是他们的业务场景是不同的,所以就需要大量的业务梳理。可能需要专门的人来梳理,就是产品经理。
我们的开发需求可能是运营到产品再到架构,最后才给到我们开发人员,经过层层传递,可能最初运营的方案和落到开发人员的方案是完全不一样的。最终所做出来的东西和运营要的可能不一样。
早期我们的领域模型可能就是数据库设计,根据业务直接建表,然后根据表的情况来进行对象映射,我们的设计流程就是建表到反推对象。这个情况如果业务进行变更,耦合度会增加,也不会满足越来越快的开发节奏。在原本的瀑布式开发是可以的,但现在互联网进入了快节奏,敏捷开发,整个项目周期都可能是实验阶段,需求随时变更。
所以我们就得用更抽象的东西来做领域建模, 领域驱动设计分为概念设计、逻辑设计、物理设计三个阶段。概念设计是概念关联图,概念类,领域类图,填充属性等。逻辑设计主要是业务罗家集和业务模型。物理设计,物理选型,可能会推翻上面理论重新定义,数据存储问题,等等。
二、领域驱动和微服务
2004年,Eric Evans发表《领域驱动设计》并且确定了领域驱动设计的核心思想:
即通过领域驱动设计方法定义领域模型,从而确定业务和应用边界,保证业务模型与代码模型的一致性。
但是提出这个概念后,DDD非常的火,但是一直没有落地的方案。直到2015年springcloudd1.0.0正式发布,springcloud netflix 2016年出现了第一个Release版本,从此一发不可收拾。
微服务的"微"到底怎么拆呢,一个多小?
这个时候领域驱动设计就起到作用了,通过领域驱动设计来划分领域模型,根据领域边界从业务角度进行微服务划分。现在很多公司已经把领域驱动设计当做微服务的指导思想了。
领域驱动用什么方式进行边界定义?
1、战略设计:从业务角度出发,建立业务模型,划分业务边界
2、战术设计:根据业务模型进行技术实现,完成软件的开发以及落地
三、DDD常见概念
1、领域
一个领域本质可以理解为就是一个问题域,只要是同一个领域,那问题域就相同。
例如:传统电商领域的问题无非订单,商品,物流,支付,库存等等,绝对不会设计到如出行,政法等相关问题,社交电商除了会有传统的电商属性外,也会附带上社交,通讯相关的功能。
2、子域
子域:你可以理解为更加细分的领域,甚至可以把子域进行更加细分,分成更多子域。
例如:电商平台看成一个领域吗,订单,仓储,物流都可以是子域,而仓储还可以划分为本地存储,三方仓库,异地仓库等。这些都可以看成是子域。
核心子域:整个业务系统的核心,所有业务都要围绕核心子域展开。
通用子域:整个领域都能够用到的子域,认证授权等模块。
支撑子域:支撑域实际上就是不包括核心竞争力的功能和通用的功能,但又是必须的支撑。
3、通用语言
一个项目中,技术专家,架构师,后端,前端,测试都会参与,但是对话的时候,可能你作为后端你会感觉产品根本get不到你的点,产品也觉得你get不到他,会出现鸡同鸭讲的问题。这时候必须有个统一的通用语言出来统一标准,能够正确简单清晰的表达业务逻辑,让项目中每个人员都能达成共识的语言。
4、限界上下文
用来封装通用语言和领域对象,提供上下文环境,保证在领域内的一些术语、业务相关对象等通用语言有一个确切的含义,没有二义性。这个边界定义了模型的适用性。
四、领域模型
也叫业务对象模型,描述业务对象之间的引用关系的。
业务对象:3种
- 业务角色:收银员,职责:计算商品价格,收钱,找零,退换货
- 业务实体:与业务角色交互需要的可交付的工件,电商项目中的商品,发票。
- 业务用例:业务角色和业务实体之间如何执行工作流程
失血模型:对象中只包含属性和get和set方法,优点就是简单,缺点所有的业务逻辑都包含在service里面是全部的业务代码,难以维护,无法应对频繁变化的需求。
贫血模型:在失血模型的基础上加上了持久层,不用在业务层去访问数据库,直接操作持久成间接的操作数据库,然后也包含一些固有行为(People的走路,吃饭,睡觉),非固有行为(people的:敲代码,打游戏,做算法题等,这些不是人人都会的)就写到service里面。优点:层次结构清楚,各层级单向依赖,对于少量业务应用来说,使用起来非常自然,开发迅速。缺点:无法应对非常复杂的场景。(用得最多)
充血模型:更符合面向对象原则,将固有行为和非固有行为全部包含在了模型当中,我们的业务层只会做整合和封装的作用,业务逻辑层很薄,符合咱们单一职责原则。缺点:开发者的水平要很高,模型中包含1大量操作,你去实例化的时候,增加很多不必要的消耗。
胀血模型:取消掉了service层,所有业务逻辑的整合都放在了领域模型中,简化了分层架构,也算是符合面向对象设计原则,取消了业务逻辑层,直接在domain object封装事务和授权,可能会授权很多原本不属于这个领域对象的逻辑,从而影响模型不稳定。代码的稳定性和维护的稳定性。
五、DDD分层架构设计
传统的三层架构
领域驱动为了更好贴近业务落地,也有自己的架构设计方法论。传统的三层模型重点在数据库,所以会以数据库作为分析的基点。而领域驱动设计的重点在领域模型,所以会以他来做分析基点。
用户界面层,显示信息给用户,对外的model,这个model不是领域层的model,会用装配器转换为应用层的model。有个箭头,是可以直接访问领域层的
应用层,规定了领域要完成的任务,与模型进行与实体无关的业务逻辑。
领域层,表达业务概念,业务信息的状态,业务规则
基础设施层,为上面层提供交互层次