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

文章链接

  1. 领域驱动设计(DDD)笔记(一)基本概念-CSDN博客
  2. 领域驱动设计(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.rhkb.cn/news/318349.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C# wpf 运行时替换方法实现mvvm自动触发刷新

文章目录 前言一、如何实现?1、反射获取属性2、定义替换方法3、交换属性的setter方法 二、完整代码1、接口2、项目 三、使用示例1、倒计时(1)、继承ViewModelBase(2)、定义属性(3)、属性赋值&am…

【目标检测】DEtection TRansformer (DETR)

一、前言 论文: End-to-End Object Detection with Transformers 作者: Facebook AI 代码: DEtection TRansformer (DETR) 特点: 无proposal(R-CNN系列)、无anchor(YOLO系列)、无NM…

pycharm配置wsl开发环境(conda)

背景 在研究qanything项目的过程中,为了进行二次开发,需要在本地搭建开发环境。然后根据文档说明发现该项目并不能直接运行在windows开发环境,但可以运行在wsl环境中。于是我需要先创建wsl环境并配置pycharm。 wsl环境创建 WSL是“Windows Su…

EasyExcel 处理 Excel

序言 本文介绍在日常的开发中,如何使用 EasyExcel 高效处理 Excel。 一、EasyExcel 是什么 EasyExcel 是阿里巴巴开源的一个 Java Excel 操作类库,它基于 Apache POI 封装了简单易用的 API,使得我们能够方便地读取、写入 Excel 文件。Easy…

【讲解下如何解决一些常见的 Composer 错误】

🌈个人主页: 程序员不想敲代码啊 🏆CSDN优质创作者,CSDN实力新星,CSDN博客专家 👍点赞⭐评论⭐收藏 🤝希望本文对您有所裨益,如有不足之处,欢迎在评论区提出指正,让我们共…

【二等奖水平论文】2024五一数学建模C题22页保奖论文+22页matlab和13页python完整建模代码、可视图表+分解结果等(后续会更新)

一定要点击文末的卡片,那是资料获取的入口! 【高质量精品】2024五一数学建模C题成品论文22页matlab和13页python完整建模代码、可视图表分解结果等「首先来看看目前已有的资料,还会不断更新哦~一次购买,后续不会再被收费哦&#…

DRF解析器源码分析

DRF解析器源码分析 1 解析器 解析请求者发来的数据(JSON) 使用 request.data 获取请求体中的数据。 这个 reqeust.data 的数据怎么来的呢?其实在drf内部是由解析器,根据请求者传入的数据格式 请求头来进行处理。 drf默认的解…

电路笔记 : 电容电阻大小表示(103、104、151、2R5、R15的含义)

电容电阻大小表示 电阻 数字索位标称法 数字索位标称法就是在电阻体上用三位数字来标明其阻值。它的第一位和第二位为有效数字,第三位表示在有效数字后面所加“0”的个数.这一位不会出现字母。如果阻值是小数.则用“R”表示“小数点”.并占用一位有效数字&#xf…

eaapp怎么改地区?eaapp账号区域更改的简单操作教程分享

eaapp怎么改地区?eaapp账号区域更改的简单操作教程分享 EA App是由Electronic Arts艺电公司开发的官方游戏平台,为玩家提供了一个集中管理和探索EA游戏世界的平台。该平台提供了丰富的游戏库,包括热门游戏如《FIFA》和《Apex Legends》等。…

C语言——小知识和小细节17

一、未能给指针成功赋值 #include <stdio.h> #include <stdlib.h> #include <string.h>void GetMemory(char* p) {p (char*)malloc(20 * sizeof(char)); }void Test() {char* str NULL;GetMemory(str);strcpy(str, "Hello World!");printf(&quo…

Java网址url工具类

功能描述 无需引入三方依赖文本匹配网址&#xff08;支持多个&#xff09;网址解析&#xff08;包括协议、主机、路径、参数等&#xff09; package com.qiangesoft.image.utils;import org.springframework.util.Assert; import org.springframework.util.CollectionUtils;i…

Flutter笔记:Widgets Easier组件库(5)使用加减器

Flutter笔记 Widgets Easier组件库&#xff08;5&#xff09;&#xff1a;使用加减器 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress…

IO端子介绍及GPIO number计算

IO端子介绍 &#xff08;引脚&#xff0c;针脚&#xff09; 嵌入式系统的主芯片&#xff0c;有的IO资源少&#xff0c;有的IO资源多。 少的是这样的封装&#xff0c;IO管脚都在四周&#xff1b; 多的是这样的封装&#xff0c;IO 的PAD都在下面&#xff1a; MCU或MPU&#xff0c…

VS(Visual Studio)中查找项目里的中文字符

目录 正则表达式查找中文字符 正则表达式查找中文字符 在Visual Studio (VS) 中查找所有的中文字符&#xff0c;你可以使用其强大的查找和替换功能。不过&#xff0c;由于中文字符的范围非常广泛&#xff08;包括简体中文、繁体中文、日本汉字、韩国汉字等&#xff09;&#xf…

[1671]jsp教材管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 JSP 教材管理系统是一套完善的java web信息管理系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为Mysql5.0&…

springcloud自定义全局异常

自行创建一个实体类 /*** 全局异常处理类**/ ControllerAdvice public class GlobalExceptionHandler {ExceptionHandler(Exception.class) ResponseBody public Result error(Exception e){e.printStackTrace(); return Result.fail();}/*** 自定义异常处理方法* param e * re…

亚马逊云科技AWS将推出数据工程师全新认证(有资料)

AWS认证体系最近更新&#xff0c;在原有12张的基础上&#xff0c;将在2023年11月27日添加第13张&#xff0c;数据工程师助理级认证(Data Engineer Associate)&#xff0c;并且在2024/1/12前半价(省75刀&#xff1d;544人民币。 原有的数据分析专家级认证(Data Analytics Specia…

【论文阅读笔记】TS2Vec: Towards Universal Representation of Time Series

【论文阅读笔记】TS2Vec: Towards Universal Representation of Time Series 摘要 这段文字介绍了一个名为TS2Vec的通用框架&#xff0c;用于学习时间序列数据的表示&#xff0c;可以在任意语义层次上进行。与现有方法不同&#xff0c;TS2Vec通过对增强的上下文视图进行层次化…

Redis 实战1

SDS Redis 只会使用 C 字符串作为字面量&#xff0c; 在大多数情况下&#xff0c; Redis 使用 SDS &#xff08;Simple Dynamic String&#xff0c;简单动态字符串&#xff09;作为字符串表示。 比起 C 字符串&#xff0c; SDS 具有以下优点&#xff1a; 常数复杂度获取字符串…

每日一题(力扣213):打家劫舍2--dp+分治

与打家劫舍1不同的是它最后一个和第一个会相邻&#xff0c;事实上&#xff0c;从结果思考&#xff0c;最后只会有三种&#xff1a;1 第一家不被抢 最后一家被抢 2 第一家被抢 最后一家不被抢 3 第一和最后一家都不被抢 。那么&#xff0c;根据打家劫舍1中的算法 我们能算出在i…