DDD[领域驱动模型]

这篇具有很好参考价值的文章主要介绍了DDD[领域驱动模型]。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

这是一种思想,不是一个工具。更多内容前往 IT-BLOG

一、领域驱动设计(DDD:Domain-Driven Design)

Eric Evans2004年提出的一种软件设计方法和理论。在应用架构的设计中,领域驱动设计DDD占据着非常重要的位置,可以说DDD是应用架构设计的核心。DDD是一套综合软件系统分析和设计的面向对象建模方法。

过去系统分析和系统设计都是分离的,正如“系统分析师” 和“系统设计师” 两种职称考试一样,这样割裂的结果导致,需求分析的结果无法直接进行设计编程,而能够进行编程运行的代码却扭曲需求,导致客户运行软件后才发现很多功能不是自己想要的,而且软件不能快速跟随需求变化。

DDD则打破了这种隔阂,提出了领域模型概念,统一了分析和设计编程,使得软件能够更灵活快速跟随需求变化。

二、DDD与数据驱动设计的区别

DDD给我们带来的是设计模式的改变。DDD的设计模式与传统的面向数据驱动的开发模式有明显的区别。
领域驱动 状态 过去,网站架构 & 性能调优,数据库,uml,java

【1】数据驱动设计从数据出发,先梳理E-R图(实体-联系图),设计数据库表结构,编写DAO,然后实现业务逻辑。数据驱动设计主要采用贫血模型[数据对象除了简单setter/getter方法外,没有任何业务方法],业务逻辑散落在大量的方法中,当系统越来越复杂时,开发和维护成本很高。
【2】DDD从领域出发,主要采用充血模型,分析领域内模型及它们之间的关系,并进行领域建模,设计核心业务逻辑,进而实现技术细节。通过DDD,定义领域模型,从而确定业务和应用的边界,保证业务与代码的一致性。

DDD最大的好处是:接触到需求第一步就是考虑领域模型,而不是将其切割成数据和行为,然后数据用数据库实现,行为使用服务实现,最后造成需求的首肢分离。DDD让你首先考虑的是业务语言,而不是数据。重点不同导致编程世界观不同。领域模型和数据模型是解耦的,有时也不是一一对应的,因此在应用DDD进行设计时,一定要摆脱数据模型优先的束缚,不要让领域模型被数据模型“绑架”,设计出合理的领域模型是首要任务。

DDD是解决复杂中大型软件的一套行之有效方式,在国外已经成为主流。DDD认为很多原因造成软件的复杂性,我们不可能避免这些复杂性,能做的是对复杂的问题进行控制。而一个好的领域模型是控制复杂问题的关键。领域模型的价值在于提供一种通用的语言,使得领域专家、产品经理和软件技术人员联系在一起,沟通无歧义。

三、DDD与微服务的关系

微服务提倡将应用划分成更细粒度的服务,服务之间互相协调、互相配合,为用户提供最终价值,是技术层面的分布式技术架构模式,是技术实现和部署的范畴。

DDD根据限界上下文设计出的领域模型和领域服务,通过微服务进行落地,并结合微服务及其他分布式技术(如DevOpsCI/CD、秒杀、全链路压测等),加速系统的落地。一个域服务可由一个微服务来实现,也可根据DDD领域分析拆分为多个微服务,对外集合成统一的域服务。

四、DDD常用的分析方法

DDD概念参考链接

DDD常用的分析方法主要有用例分析法四色建模法事件风暴法、领域故事讲述、用例法、战术设计、战略设计、洋葱框架、六边形架构、分层架构、CQRSCOLA等。

用例分析法

比较传统的需求调研过程中结合领域模型的设计思路进行,核心是通过业务需求、场景流程等梳理用例,进而规划领域模型。

用例分析的前提是业务架构的需求输入,其中核心是业务能力与业务流程

比如电商领域的订单寻源、库存锁定、商品价格计算、优惠券核销等业务能力,以及订单处理、分单和拆单、逆向退款等业务流程。

编写用例时要避免使用技术术语,应该使用最终用户或者领域专家可以理解的语言,进而我们可以基于用例分析法,根据语义来整理用例,然后整理领域模型,大概步骤如下。
领域驱动 状态 过去,网站架构 & 性能调优,数据库,uml,java

收集用例: 从业务能力、业务流程、业务需求描述中进行提取,收集相应的名词、动词、形容词,以及对应的业务场景
提取实体: 从名词中定位出主要实体,如商品、SKU、品类等。
提取属性: 从形容词中添加实体属性,如颜色、价格等。
添加关联: 从动词或形容词中添加实体和实体之间的关联,如商品“包含”SKU,卖家“开设”“多家”店铺等。
完善模型: 识别出初步模型,验证并迭代模型,同时补充用例验证模型、业务流程验证模型。

举个关于电商的例子:假设有这样的需求描述:“会员使用代金券兑换了很多促销的商品。”
我们先从名词“会员”“代金券”“商品”中提取实体,并从形容词“促销的”提取商品的属性,进而将动词“使用”“兑换”识别成关联,同时结合行业知识得知,代金券属于优惠券的一种,最终得出领域模型。
领域驱动 状态 过去,网站架构 & 性能调优,数据库,uml,java

四色建模法

四色建模法在实践中也比较常用,其包括以下几个核心概念。

时间记录(Moment-Interval): 具有可追溯性的记录运营或管理数据的时刻或时段对象(如用粉红色表示)。
人、地、物(Party-Place-Thing Archetype,PPT): 代表参与到流程中的参与方、地点、物(如用绿色表示)。
角色(Role): 在时间记录与PPT对象(通常是参与方)之间参与的角色(如用黄色表示)。
描述(Description): 对PPT对象的一种补充描述(如用蓝色表示)。

简单地说,四色建模法关注的是,某个人(Party)的角色(PartyRole)在某个地点(Place)的角色(PlaceRole)用某个东西(Thing)的角色(ThingRole)做了某件事情(Moment-Interval)。

下面以一个课程报名缴费的例子对四色建模法进行说明:
报名人可以为学生进行报名,产生对应的报名登记记录和课程表,进而缴费人进行缴费,产生缴费记录。
在这个过程中,“人”有学生和课程,对应的“角色”是报名人和缴费人,完成的“时间记录”是报名登记记录、课程表及缴费记录,再加上一些补充描述。
领域驱动 状态 过去,网站架构 & 性能调优,数据库,uml,java

事件风暴法

事件风暴又称事件建模,与头脑风暴类似,可以快速分析复杂的业务领域,完成领域建模的目标。事件风暴是事件驱动设计的典型代表,是一种快速、轻量且未得到充分认可的群体建模技术,它对于加速开发团队非常适用。

事件风暴法关注以下元素:
事件: 发生了什么事情,产生了什么结果(如用橘黄色表示)。
属性: 事件的输入、输出,是对时间的细化描述。
命令: 某个动作的发起者,可能是人、外部事件、定时器等(如用蓝色表示)。
领域: 领域的聚合、内聚、低耦合,聚合内部保证数据的一致性(如用黄色表示)。

简单理解就是谁在何时基于什么(输入)做了什么(命令),产生了什么(输出),影响了什么(事件),最后聚合成了什么(领域)。

事件风暴催化并加速整个建模过程,强调正确的人(业务人员、领域专家、技术人员、架构师、测试人员等关键角色都要参与其中)、开放空间(有足够的空间可以将事件流可视化,让人们可以交互讨论)、即时贴(至少三种颜色),关联的人充分讨论,集体决策,从价值角度来审视业务流程的合理性。领域事件容易促使业务人员和非业务人员达成共识。

下面通过一个电商的例子说明事件风暴的主要过程:
【1】基于业务流程和业务流程的输入,对事件进行头脑风暴,主要识别应用层面的主要状态结果。比如识别出“商品已创建”,“库存已扣减”,“订单已支付”等。
【2】识别命令,即什么人做什么事,可以识别出运营人员可以添加商品和编辑库存,用户可以创建订单,并伴随着对应的事件。
【3】进行聚合,即将相关的实体聚合在一起,可以看到商品、库存、订单三个领域初步识别,并与相关的命令和事件结合在一起。
【4】对这些领域进行边界划分,识别出对应的限界上下文。
领域驱动 状态 过去,网站架构 & 性能调优,数据库,uml,java

五、DDD分层架构

DDD在具体落地实施的过程中,强调四层分层结构,将核心概念进行有效的整合,各层的职能定义如下。
领域驱动 状态 过去,网站架构 & 性能调优,数据库,uml,java

展示层(Facade Layer): 负责与不同用户和应用之间的交互协议和数据格式的转换,因此它又叫用户接口层。
应用层(Application Layer): 应用层是很薄的一层,负责展示层与领域层之间的协调,它是与其他系统的应用层进行交互的必要渠道,负责对领域层组件进行简单封装,例如事务、调用应用程序的任务。应用层要尽量简单,其服务及方法一般以用例为对应关系,通常一个用例对应到一个应用层的服务方法,方法中不包含业务规则或者知识,不保留业务对象的状态,只保留应用任务的进度状态,更注重业务能力或者业务流程的相关展示。主要通过调用领域层和基础设施层来完成协调。
领域层(Domain Layer): 领域层是DDD的核心,包含一些核心概念,如领域实体、值对象、领域服务、聚合,以及它们之间的关系。它主要负责表达业务概念、业务状态信息及业务规则,具体表现形式是领域模型。DDD提倡充血模型,即尽量将业务逻辑归属到领域对象上。
基础设施层(Infrastructure Layer): 基础设施层向其他层提供通用的技术能力,为应用层传递消息(如API网关等),为领域层提供持久化机制(如数据库资源、中间件交互等),屏蔽技术底座能力(如底层服务的健康度检查、配置参数等)及其他通用的工具类服务。

除了比较经典的四层分层架构,DDD还有一种松散分层架构,即端口适配器架构。
领域驱动 状态 过去,网站架构 & 性能调优,数据库,uml,java

端口适配器架构通过划分内部和外部,系统由内而外围绕领域模型展开。领域部分位于最内层,应用程序包含领域模型和业务逻辑,对于外部而言,通过各种适配器进行上下文集成,包括数据持久化、第三方数据集成,同时基于依赖注入和Mock机制,适配器完成便捷的替换和模拟。

不论哪种分层架构,都遵循以下几个通用的DDD分层原则:
无环依赖原则: 组件的依赖关系中没有环路,如果出现,则需要打破循环依赖。
稳定依赖原则: 被依赖者应该比依赖者更稳定,同时组件的抽象程度应该与其稳定程度保持一致。一个稳定的组件应该是抽象的,这样便于扩展。
依赖倒置原则: 高层次的模块不应该依赖低层次的模块,它们都应该依赖抽象。抽象不应该依赖具体,具体应该依赖抽象。

六、实战

以渠道中心(一个微服务)作为例子来做领域模型设计,核心就是设计2个图,一个是战略设计图(宏观) ,一个是战术设计图(细节)。

领域战略设计图

战略设计图是从一个限界上下文的角度出发去分析业务场景。主要是宏观上的核心域、子域、实体关系图。demo如下图:
领域驱动 状态 过去,网站架构 & 性能调优,数据库,uml,java

领域战术设计图

战术设计图是从一个限界上下文的角度出发去分析业务场景。细化到核心业务字段、领域实体、值对象、领域服务、领域事件等等。基本上这个图画完,代码已经知道怎么写了。demo如下图:
领域驱动 状态 过去,网站架构 & 性能调优,数据库,uml,java

技术实现

整体项目框架分层图如下所示:
领域驱动 状态 过去,网站架构 & 性能调优,数据库,uml,java

4层典型DDD分层结构:
【1】展现层: controller层,无业务逻辑。
【2】应用服务层: 此层可以包含查询逻辑,但核心业务逻辑必须下沉到领域层。
【3】领域服务层: 业务在这里组装。仓储(资源库)接口在此层定义。
【4】基础设施层: 仓储(资源库)实现层+PO持久化层。

服务调用问题

域内调用: 领域内调用,随便调用,丝般顺滑。至于实现,可以由一个核心域的仓储实现层(第四层)去实现多个Repository接口。(比如这里A是核心域的实体名,B是支撑域、通用域等)
领域驱动 状态 过去,网站架构 & 性能调优,数据库,uml,java

跨域调用: 使用领域事件eventbus来做解耦,考虑是否有可能合并为一个领域。跨上下文(肯定跨域):ACL层->Adapter适配器层->feign调用
领域驱动 状态 过去,网站架构 & 性能调优,数据库,uml,java

包结构

包结构如下:
领域驱动 状态 过去,网站架构 & 性能调优,数据库,uml,java

展开包结构如下:

领域驱动 状态 过去,网站架构 & 性能调优,数据库,uml,java

展现层: Controller仅做接口的入口定义和编排转发,不做任何的业务处理。
应用服务层: application负责接口参数DTO的简单校验,以及DTO和实体值对象的数据转换,对于简单的业务,也可以在应用层加载实体直接执行实体行为方法。

领域层
模型: 根据领域模型分析领域内各实体、聚合、聚合根、值对象等,这些对象在*.domain.model定义,实体内的行为方法只负责维护实体自身的生命周期和状态。
行为: 领域内各实体、聚合、聚合根等,会有相应的行为,在*.domain.model包下定义行为方法。
领域服务: 领域提供的接口服务,需要定义在*.domain.service包下,业务相关的前置业务判断、多个实体或值对象的行为逻辑处理等,都在领域服务中实现,需要注意的是并不是每个实体都有一个对应的领域服务,但是依赖多个实体的行为方法,最好根据这个业务模块是建立一个领域服务。
仓储: 领域服务或上层应用服务需要使用到的基础设施层,包括DBFeign调用等,定义在*.domain.repository下,在*.infrastructure.repository下实现。
适配层:acl包下的feign定义依赖外部的接口,并在acladapter包编写转换,由仓储层操作实体时调用。

持久层: 与常用DAO定义一致,由仓储层操作实体时调用。文章来源地址https://www.toymoban.com/news/detail-761968.html

到了这里,关于DDD[领域驱动模型]的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 快速理解DDD领域驱动设计架构思想-基础篇 | 京东物流技术团队

    快速理解DDD领域驱动设计架构思想-基础篇 | 京东物流技术团队

    本文与大家一起学习并介绍领域驱动设计(Domain Drive Design) 简称DDD,以及为什么我们需要领域驱动设计,它有哪些优缺点,尽量用一些通俗易懂文字来描述讲解领域驱动设计,本篇并不会从深层大论述讲解落地实现,这些大家可以在了解入门后再去深层次学习探讨或在后续进阶

    2024年02月09日
    浏览(6)
  • 软件架构演进过程与微服务设计中的领域驱动设计(DDD)

    软件架构的演进是一个不断改进和解决问题的过程。从传统架构到面向服务架构(SOA),再到微服务架构,每个阶段都带来了新的技术和解决方案。而在微服务架构中,领域驱动设计(DDD)起着至关重要的作用,它能够提高系统的可扩展性、可维护性和可理解性。本文将介绍软件架

    2024年02月16日
    浏览(5)
  • 领域驱动设计——DDD领域驱动设计进阶

    领域驱动设计——DDD领域驱动设计进阶

    进阶篇主要讲解领域事件、DDD 分层架构、几种常见的微服务架构模型以及中台设计思想等内容。如何通过领域事件实现微服务解耦?、怎样进行微服务分层设计?、如何实现层与层之间的服务协作?、通过几种微服务架构模型的对比分析,让你了解领域模型和微服务分层的作

    2024年01月15日
    浏览(8)
  • DDD领域驱动设计(六)

    领域对象需要资源存储。存储手段多样化,常见就是数据库,分布式缓存,localCache.资源库的作用,就是对领域的存储和访问进行统一管理对象。在抽奖平台中。通过下面这种方式组织资源库。

    2024年01月24日
    浏览(5)
  • DDD领域驱动

    DDD领域驱动

    我们经常讲技术为业务服务,架构设计需要对业务充分理解,在面向复杂的业务场景时,会面临诸多问题: 复杂系统设计 :业务系统多、业务类型多、业务相互耦合,有没有合适的方法来指导模块的边界开发? 多团队协同 :业务系统边界划分不清,系统间依赖复杂,往往一

    2024年02月09日
    浏览(7)
  • 领域驱动设计DDD实际项目落地最佳实践

    领域驱动设计DDD实际项目落地最佳实践

    领域驱动设计(Domain Driven Design,简称:DDD)设计思想和方法论早在2005年时候就被提出来,但是一直没有被重视和推荐使用,直到2015年之后微服务流行之后,再次被人重视和推荐使用。 下面我来介绍一下DDD设计思想和方法论,同时结合我们在实际项目中应用总结和思考。 目录

    2024年02月08日
    浏览(28)
  • DDD进阶_领域事件是什么?如何开展领域事件驱动开发工作?

    DDD进阶_领域事件是什么?如何开展领域事件驱动开发工作?

    DDD从入门到精通,系列文章传送地址,请点击本链接。   目录 一、什么是领域事件 二、如何识别领域事件 三、领域事件的数据一致性 四、领域事件分类 1、微服务内的领域事件 2、微服务之间的领域事件 五、领域事件案例 六、领域事件总体架构图 1. 事件构建和发布 2、事

    2024年02月15日
    浏览(5)
  • 万字长文助你上手软件领域驱动设计 DDD

    万字长文助你上手软件领域驱动设计 DDD

    最近看了一本书《解构-领域驱动设计》,书中提出了领域驱动设计统一过程(DDDRUP),它指明了实践 DDD 的具体步骤,并很好地串联了各种概念、模式和思想。因此,我对书本内容做了梳理、简化,融入自己的理解,并结合之前阅读的书籍以及实践经验,最终形成这篇文章。

    2024年02月08日
    浏览(7)
  • 设计一个亿级高并发系统架构 - 12306火车票核心场景DDD领域建模

    设计一个亿级高并发系统架构 - 12306火车票核心场景DDD领域建模

    “ 架设一个亿级高并发系统,是多数程序员、架构师的工作目标。 许多的技术从业人员甚至有时会降薪去寻找这样的机会。但并不是所有人都有机会主导,甚至参与这样一个系统。今天我们用12306火车票购票这样一个业务场景来做DDD领域建模。” 要实现软件设计、软件开发

    2024年02月03日
    浏览(4)
  • 【架构师成长之领域驱动开发】

    项目中的“坏”味道 可维护性差:大量的第三方模块影响核心代码的稳定性 可扩展性差:业务逻辑与数据存储相互依赖,无法复用 可测试性差:庞大事务脚本与基础设施强耦合,无法单元测试。 最后的结果:业务发生几次迭代后,这段代码就将成为一个可怕的黑洞。 高内

    2024年02月01日
    浏览(8)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包