领域驱动设计(DDD)笔记(一)基本概念

news2025/1/12 22:58:30

文章链接

  1. 领域驱动设计(DDD)笔记(一)基本概念-CSDN博客
  2. 领域驱动设计(DDD)笔记(二)代码组织原则-CSDN博客
  3. 领域驱动设计(DDD)笔记(三)后端工程架构-CSDN博客

DDD基本概念

  1. DDD 是一种面向复杂需求的软件设计方法,将软件开发核心业务概念深度联系起来,设计出不断发展的模型
  2. DDD 目标概述
    1. 将主要重点放到核心领域和领域逻辑上(core domain
    2. 复杂的业务逻辑的实现设计体现在领域模型上
    3. 在技术专家和领域专家直接发起创造性合作,不断晚上特定领域下的概念模式
  3. DDD 名称解释
    1. 领域是一系列业务知识业务行为的集合
      1. 比如金融领域:商户、客户、用户等领域专家从事活动、积累经验、掌握知识的集合
      2. 比如医疗领域: 医生、护士等领域专家从事活动、积累经验、掌握知识的集合
    2. 领域专家:领域专家不是一个职位;他可以是精通业务的任何人,了解业务领域知识,他们可能是相关从业者、产品经理、开发者、QA、销售等等。
    3. Model:领域模型是关于某个特定业务领域人软件模型。通常领域模型通过对象模型实现,这样对象同时包含了数据和行为,表达了准确的业务含义。
    4. Ubiquitous language
      1.  通用语言指的是一种围绕域模型构建的语音,由所有团队成员在限界上下文中使用,将团队和活动软件联系起来。比如在财经领域: 直连、间连、收单、退款
      2. 只有团队中所有成员都使用了通用语言(所有的词语、概念都是明确的),才能保证我们各方的理解是正确的;团队内成员合作是紧密高效的;是能激发团队内成员的创造力的。
    5. Context :上下文指的是一个人为设定,确定了上下文环境后,我们才能确定词语或语句的含义。只有在一个明确的上下文中,模型才能被理解。
    6. Bounded context
      1. 限界上下文是一个程序之内的概念性边界。在这个边界之内的每种领域术语、词组或者句子,都有明确的上下文含义。在这个边界之外,这些术语可能表示不同的意思。比如:用户这个概念,在在线问诊上下文中,是在线问诊被服务方,与医生概念相对;而在头条账号上下文中,则是注册账号的自然人实体,不区分用户、医生。
      2. 另外,相同一个客观物体,在不同的限界上下文中,关心的概念和细节也是不同的。 如,一个产品在商品上下文中,被称为商品,关心的是商品的规格、价格等信息;在物流上下文中,被称为货物,关心的则是仓储地、发货地、目的地等信息。

DDD的好处和限制

好处

  • 使领域专家和开发者一起工作,软件可以准确的传达业务规则
  • “准确传达业务规则”是指软件就像领域专家开发出来的一样
  • 可以帮助业务开发自我提高 在DDD中每个人都在学习,都是知识的共享者
  •  团队的沟通效率和协作效率变得更高,统一模型语言,团队成员之间不存在翻译,或者减少翻译
  • 对技术研发而言DDD分为战略设计和战术设计,以代码为界线上下文作为服务领域边界,代码开发始终围绕着领域中的关键模型
  • 更好的指导我们划分服务、领域、设计更清晰的架构
  • 指导我们写出更清晰、容易维护、符合SOLID原则的代码

限制

  • DDD只适用于领域复杂、业务逻辑复杂的情况,它不适用于领域相对简单,但技术复杂的应用程序
  • DDD学习曲线陡峭,需要在团队内反复实践,并且大家的认识也不一定一致
  • DDD设计非常耗时,并且需要强大的领域专业知识。它需要领域专家的参与,所以需要根据项目实际情况决定是否使用DDD
  • DDD设计是发展的,不是一蹴而就。需要知行结合,长期不断投入精力迭代

业务理解工具

可以使用业务模型画布(bussiness model canvas)来描述业务模型,可以使用用户故事图(user story mapping)来了解业务。

用户故事图:

发现领域(四步法)

        如何发现领域是DDD关键环节,如果整个团队没有很好的理解领域,软件决策有可能被误导,所谓发现领域,继需要我们各方协作,以可视化的方式发现业务模型中存在的领域。之后我们确保领域知识在整个团队中传播,使得所有成员能够为改进产品做出贡献。

        需要说明的是发现领域的过程是持续不断的,我们总能在互相沟通中,不断细化对领域的理解,发现当前领域的不足

        发现领域往往是最难的一步,这个阶段我们需要和领域专家进行深入、频繁的交流。最近方法是多次组织领域专家会议,并且尝试理解该领域中的知识。

        在这个过程中,我们会收到很多学习;包括业务场景、角色、行为动作、产生影响等。我们可以使用事件风暴(event storming)方法,将这些离散数据串联为一个个业务场景,并归纳为领域

第一步,我们和领域专家一起分析业务,收集一下离散事件;参与人包括:设计、构建、测试软件的人、拥有领域知识的人、了解产品战略的人、了解客户需求的人 。

第二步,将收集到的事件按照时间排序,尝试找出中间缺失的环节

第三步,细化时间,为事件补充细节:

第四步,重新排序和总结,尝试对事件进行分类

各颜色代表的含义

识别核心领域

        从工程角度而言,我们的时间和资源是有限的;从业务领域而言,我们总是感知到业务例最核心最重要的部分;因此了解领域的那些部分对业务产生最重要的影响至关重要,通过分析出核心领域是什么,我们更好的做出决策出构建系统的每个部需要多严谨、多稳定;哪些需要购买或者外部。

核心域:是让业务与众不同的地方,一个业务如果不在其核心领域表现出色,就不可能成功(甚至无法存在)。因此为核心域设计是如此重要;核心域设计是最高优先级、最大努力、最好的开发人员。对于较小的领域可能只有一个核心域,较大的可能有多个。(比如电商的支付场景的下单、结算中的订单模型和相关的接口就属于核心域)

支撑域:业务成功必须有的子域,但不属于核心域;它也不是通用的,因为他仍然需要相关程度的专业化或者特异化(比如订单的管理、订单的审核对应的操作页面和后台就属于支撑域)

通用域:它不包含组织特殊内容,但仍需要整个行业解决方案才能正常工作。通过尝试为通用子域找到现成的软件可以大量节省时间和工作。比如用户身份管理、单点登录。

举个例子,假设我们在搭建电商的管理系统,我们已经确定了以下子域:

  • merchant_info: 用于提高电商的商户信息操作的基本接口
  • merchant_admin: 用于进行电商商户的业务管理,比如入驻审核、体现管理、风险控制等
  • settlement: 用于商户的清结算业务
  • file archive:用于存储和管理商户的非结构化数据(营业执照照片、身份证照片等)
  • sign:用于完成电商的签约和合同管理

现在我们开始进行分类:

        

确定领域模型的业务边界(限界上下文职责描述)

限界上下文既然作为一个显式边界,那么我们必须用更具体的语言去描述它,以便团队内所有成员对其的认识是一致的,以下举例一个膜拜,回答这些问题就是在描述领域模型的边界

举个贷款评估的例子

上下文映射(各个领域上下游之间的映射关系)

        当我们定好所有上下文后,我们需要考虑各个上下文的直接的关系;我们引入上下文映射(context map);下面介绍几种常见的映射关系;方便我们日常选择。

  • 合作关系(Partnership):准确来说这是在描述团队、上下文间的关系,而且是一种技术上的模式。它们建立了一种共同制定开发计划、共同管理的合作方式。
  • 共享内核(Shared Kernel):  从领域模型中选出两个团队都同意共享的一个子集。除了模型的这个子集以外,可能还包括与该模型部分相关的代码子集.或数据库设计的子集。这部分明确共享的内容具有特殊的状态,而且一个团队在没与另一个团队商量的情况下不应擅自更改它,共享内核不能像其他设计部分那样可以自由更改。 在做决定时需要与另一个团队协商。当修改共享内核时,必须要通过两个团队的所有测试。例如,医学nlp上下文和视频审核上下文可以是共享内核关系。因为共享内核会导致两个上下文依赖很重,不推荐大家使用。
  • 客户方-供应方开发(Customer-Supplier Development):在两个团队之间建立一种明确的客户/供应商关系。下游团队相当于上游团队的客户。根据下游团队的需求来协商需要执行的任务并为这些任务做预算,以便每个人都知道双方的约定和进度。两个团队一起开发自动验收测试,用来验证预期的接口。把这些测试添加到上游团队的测试case中,以便作为其持续集成的一部分来运行。这些测试使上游团队在做出修改时不必担心对下游团队产生副作用。 这也是我们最常见的合作模式之一。
  • 遵奉者(Conformist):下游上下文只能盲目依赖上游上下文。例如,支付上下文和支付宝渠道通知上下文,就是遵奉者模式,支付上下文作为客户方只能遵循上游的协议和术语。
  • 防腐层(Anticorruption Layer):  一个上下文通过一些适配和转换与另一个上下文交互。防腐层其实是设计思想“间接”的一种体现,引入一个中间层,有效隔离限界上下文之间耦合。防腐层往往属于下游限界上下文,用以隔绝上游限界上下文可能发生的变化,减少对上游不必要的依赖。
  • 开放主机服务(Open Host Service): 定义一种协议来让其他上下文来对本上下文进行访问。开放这个协议,以便所有需要与你的子系统集成的人都可以使用它。当有新的集成需求时,就增强并扩展这个协议。例如,问诊IM提供的通用模板消息,可以认为是一种开放主机模式。
  • 发布语言(Published Language): 通常与OHS一起使用,用于定义开放主机的协议。把一个文档化良好的、能够表达出所需领域信息的共享语言作为公共的通信媒介,必要时在其他信息与该语言之间进行转换。例如,redis通信协议可以被认为是一种PL,redis和字节内部的abase等都可以使用该协议通信;opentracing定义的事件协议,也可以是一种PL。
  • 大泥球(Big Ball of Mud):混杂在一起的上下文关系,边界不清晰。当我们检查已有系统时,经常会发现系统中存在混杂在一起的模型,它们之间的边界是非常模糊的。此时,我们应该为这个混乱的系统划定一个边界,将其纳为大泥球的范畴。在这个边界之内,不要尝试使用复杂的建模手段来解决问题,并要时刻警惕不要让混乱的模型影响其他系统。
  • 另谋他路(SeparateWay): 两个完全没有任何联系的上下文。让两个上下文扯上关系,总是有成本的。这种“无关系”仍然是一种关系额,而且是最好的一种关系。通过定义一个足够小、与其他上下文无关的上下文,让我们聚焦在这个小的领域,找到最简单、专用的解决方案。例如,全网作者库和抖音作者库集成到一个平台可能很麻烦,需要考虑很多问题。那么我们就让这两个上下文毫无关系,使用不同的方案去实现,比如都链接到已有平台。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1641555.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

嵌入式开发四:STM32 基础知识入门

为方便更好的学习STM32单片机,本篇博客主要总结STM32的入门基础知识,重点在于理解寄存器以及存储器映射和寄存器映射,深刻体会STM32是如何组织和管理庞大的寄存器,从而提高开发效率的,为后面的基于标准库的开发做好铺垫…

Elasticsearch:对 Java 对象的 ES|QL 查询

作者:Laura Trotta ES|QL 是 Elasticsearch 引入的一种新的查询语言,它将简化的语法与管道操作符结合起来,使用户能够直观地推断和操作数据。官方 Java 客户端的新版本 8.13.0 引入了对 ES|QL 查询的支持,提供了一个新的 API&…

手撸Mybatis(四)——连接数据库进行简单查询

本专栏的源码:https://gitee.com/dhi-chen-xiaoyang/yang-mybatis。 添加数据库操作模板 对于JDBC操作,一般包括以下几个步骤: 1)注册驱动 2)建立连接 3)执行sql语句 4)处理结果 5&#xff09…

【neteq】tgcall的调用、neteq的创建及接收侧统计

G:\CDN\P2P-DEV\Libraries\tg_owt\src\call\call.cc基本是按照原生webrtc的来的:G:\CDN\P2P-DEV\tdesktop-offical\Telegram\ThirdParty\tgcalls\tgcalls\group\GroupInstanceCustomImpl.cpptg对neteq的使用 worker 线程创建call Call的config需要neteqfactory Call::CreateAu…

Boosting算法揭秘:从原理到scikit-learn实战

Boosting算法揭秘:从原理到scikit-learn实战 在机器学习的江湖中,Boosting算法以其强大的预测能力和独特的训练方式占据了一席之地。与Bagging算法并行训练的理念不同,Boosting算法更注重模型的串行迭代和错误修正。本文将从Boosting算法的基…

JVM笔记1--Java内存区域

1、运行时数据区域 从上图可以看出来,Java虚拟机运行时数据区域整体上可以分成5大块: 1.1、程序计数器 程序计数器是一块较小的内存空间。它可以看做当前线程所执行的字节码的行号指示器。在Java虚拟机的概念模型里,字节码解释器工作时就是…

【热门话题】Chrome 插件研发详解:从入门到实践

🌈个人主页: 鑫宝Code 🔥热门专栏: 闲话杂谈| 炫酷HTML | JavaScript基础 ​💫个人格言: "如无必要,勿增实体" 文章目录 Chrome 插件研发详解:从入门到实践一、引言二、Chrome 插件基础概念…

汇编语言——输入两个字数据(16位的数)X,Y,计算Z=X+Y,并把Z的结果显示出来

文章目录 以2进制输入,2进制输出(无符号)以2进制输入,2进制输出(带符号)以8进制输入,8进制输出以10进制输入,10进制输出以16进制输入,16进制输出 仅供参考 X、Y的输入可…

08 - 步骤 表输出

简介 表输出(Table Output)步骤是用于将 Kettle 中的数据写入关系型数据库表的步骤。它允许用户将数据流中的数据插入、更新或删除到目标数据库表中。 使用 场景 我要将处理完的数据流中的sysOrgCode 跟 plateNumber 保存记录到mysql 1、拖拽表输出…

目标检测算法YOLOv5简介

没有关于YOLOv5的直接论文,YOLOv5由Ultralytics维护,源码见:https://github.com/ultralytics/yolov5 ,于2020年6月发布v1.0版本,最新发布版本为v7.0,License为AGPL-3.0. 以下内容主要来自: 1. U…

MyScaleDB:SQL+向量驱动大模型和大数据新范式

大模型和 AI 数据库双剑合璧,成为大模型降本增效,大数据真正智能的制胜法宝。 大模型(LLM)的浪潮已经涌动一年多了,尤其是以 GPT-4、Gemini-1.5、Claude-3 等为代表的模型你方唱罢我登场,成为当之无愧的风口…

【R语言数据分析】卡方检验

目录 交叉卡方检验 配对卡方检验 趋势卡方检验 交叉卡方检验 交叉卡方表用于比较组间“率”的差异。适用于分类型变量,被检验的分类变量应该是无序分类变量,分组变量可以是有序分组也可以是无序分组。比如比较两种药物治疗某个疾病的效率,…

Bartender 5 - MacBook菜单栏图标管理软件

当 macOS 桌面图标太多时,既不美观又经常会相互遮盖,非常影响操作。 苹果现在还把「刘海屏」发扬光大,MacBook 的菜单栏是越来越不方便了! 如果你希望 Mac 的菜单栏干净清爽、又方便易用,那「Bartender 5」你一定要试…

第15章 基于规格说明的测试技术

一、概述 (一)依据 《软件需求规格说明书》以及对应的模型或用户需求。 (二)特点 不考虑内部结构和内部特征 (三)测试用例满足的标准 利用黑盒测试技术导出测试用例 (四)测试…

基于 Wireshark 分析 ICMP 协议

一、ICMP 协议 ICMP(Internet Control Message Protocol)即互联网控制报文协议,是TCP/IP协议簇的一个子协议。它主要用于在IP主机、路由器之间传递控制消息,这些消息涉及网络是否通畅、主机是否可达、路由是否可用等关于网络本身…

2024年北京高校后勤餐饮博览会|北京餐饮展览会

高联采高校后勤餐饮博览会 暨第25届北京高校后勤餐饮联合招标采购大会 同期举办:中国北京餐饮供应链博览会 主 题: 因为FOOD校园GOOD / 同创高校大舞台共享精彩高联采 时 间:2024年9月21日-22日 地 点:中国国际展览中心&…

利用大模型提升个性化推荐的异构知识融合方法

在推荐系统中,分析和挖掘用户行为是至关重要的,尤其是在美团外卖这样的平台上,用户行为表现出多样性,包括不同的行为主体(如商家和产品)、内容(如曝光、点击和订单)和场景&#xff0…

【Hadoop】--基于hadoop和hive实现聊天数据统计分析,构建聊天数据分析报表[17]

目录 一、需求分析 1、背景介绍 2、目标 3、需求 4、数据内容 5、建库建表 二、ETL数据清洗 1、数据问题 2、需求 3、实现 4、扩展概念:ETL 三、指标计算 1、指标1:统计今日消息总量 2、指标2:统计每小时消息量、发送量和接收用…

python学习笔记----面向对象(十)

一、什么是类 类是一个抽象的模板,用于创建具体的实例。可以将类理解为一个蓝图,它定义了一系列对象共有的属性(数据)和方法(函数)。类是对一组具有相同属性和功能的对象的抽象。例如,你可以定…

FIFO Generate IP核使用——Native读写接口信号详解

Native FIFO接口信号是用于FIFO IP核与外部电路进行通信的信号。当FIFO支持独立的写和读时钟时,这些信号可以包括标准端口和可选端口。 1 当FIFO具有独立时钟时的接口信号 当FIFO具有独立的时钟时,其接口信号会相应地有所变化。特别是关于复位信号rst…