领域驱动设计-Domain-Driven-Design概念

2023-11-10

2021了,你应该要了解DDD了,不然领导和你吹牛你都听不懂,或者你都没法和别人吹牛了

一、Evans DDD 是什么

1.1 背景

  • 2002年,敏捷宣言诞生
  • 时代处于 CS 到 BS 的转换时期
  • 2003年 Eric Evans 发表<领域驱动设计>
  • 2013年 微服务诞生,微服务的拆分和边界限定成为了难点,因而DDD思想开始重新发挥作用

1.2 描述

  • 2003 Eric Evans : Domain-Driven Design - Tackling Complexity in the heart of Software 领域驱动设计
  • 领域建模是一种艺术的技术
  • 面向对象建模方法,是一种工程方法论
  • 是用来解决大型复杂软件快速应付变化的解决之道
  • 属于业务架构设计范畴
  • 使系统有较好的一致性和良好的扩展性

1.3 重要性

  • 没有领域模型,只靠代码编写,复杂的领域需求会使得他们无法交流讨论,使工作陷入泥沼
  • 有少许领域模型,没有维护好模型和代码之间的联系,两者产生差异,无法实现

1.4 存在的问题

  • 自身概念复杂,学习难度大,门槛高
  • 国内实践少,参考少,尝试成本高
  • 敏捷迭代,使得项目放弃了建模

二、为什么使用MDD/DDD

2.1 MDD 模型驱动设计

2.2 MDD = DDD+DSL(领域特定语言)

2.3 优点

  • 真正快速开发

  • 更具成本优势

  • 引导质量提高

  • 很少出错

  • 不在乎人事变动

  • 授权领域专家

  • 能够让高级程序员专攻难关

  • 让业务和IT之间架设了桥梁

  • 减少业务需求带来的影响面

  • 导致技术对变化不是太敏感

  • 增强架构

  • 可以截获领域知识

  • 能够关注业务而不是技术

  • 架构发展阶段

    • 单体
    • MVC
    • SSM
    • 分层
    • DDD分层
    • 对称性分层

三、软件开发本质

3.1 问题空间

  • 需求、用例、业务分析

    • 领域问题:一个特定边界内的业务需求总和

3.2 解决方案空间

  • 模型、组件、架构、设计实现

    • 领域模型:是业务功能场景在软件系统的映射转化

3.3 映射转化

四、分析设计发展阶段

4.1 主要阶段

  • 围绕数据库的驱动设计

    • 设计从数据库表设计开始
  • 面向对象的分析设计

    • 区分分析和设计阶段,两个阶段是比较割裂的
  • 融合了分析和设计阶段的领域驱动设计

4.2 不同阶段局限性

  • 传统数据库方式的局限性

    • 分析方面

      • 不能迅速有效全面分析需求
    • 设计方面

      • 导致过程化设计编程,丧失了面向对象设计的特点,对象仅成为数据的载体
    • 运行方面

      • 导致软件运行时负载集中在数据库端,难于扩展
    • 其他

      • 对象与关系型数据库的天然阻抗

        • 库表关系不能真正还原对象之间的联系,需要额外字段
        • CRUD的操作,不能直观标识对对象的意图
        • 数据模型和关系模型存在偏差
  • 面向对象:分析和设计割的局限性

    • 分析人员负责从问题空间领域汲取需求,即从需求领域着手
    • 设计人员:剥离出能够通过编程构建的组件,组件间能够有效运作,解决应用程序的问题
    • 迭代的需求,不能很好的分析,由设计人员按照数据的逻辑进行拼凑
    • 两个阶段目标不一致,导致割裂,项目失败

4.3 DDD领域模型特点

  • 统一语言/通用语言

    • 项目中统一交流的语言,提高交流效率、工作效率、避免理解错误与误解、沟通低效
    • 让应用能和业务相匹配,通过在业务与代码中的技术之间采用共同的语言达成的
  • 统一领域模型

    • 只有业务,没有技术
    • 表达需求真实世界的模型,和软件技术无关
    • 通过分层,将领域模型层突出,其他为辅助

五、分层架构

5.1 分层详情

  • 表现层

    • 与MVC的V类似,关注显示和用户指令
  • 应用层

    • 与MVC的C类似,指挥领域对象实现功能,精简
  • 领域层

    • 核心业务概念
  • 基础支撑层

    • 与MVC的M类似,与软件技术相关

5.2 分层架构优点

  • 不同层级,能够保证高内聚低耦合,有利于程序分布式部署、提升心梗、高可伸缩性

六、DDD实施的注意点

6.1 挖掘核心深层模型

6.2 剔除反面通用子域

6.3 内聚机制

6.4 隔离核心

6.5 领域模型切割

6.6 行为型设计模式

  • 模板方法
  • 策略
  • 状态
  • 命令
  • 迭代器
  • 备忘录
  • 观察者
  • 中介者
  • 访问者
  • 责任链
  • 解释器

七、领域模型元素

7.1 实体

  • 拥有业务含义的全局唯一标识符,拥有生命周期,且标识符在经历软件系统的各种状态,生命周期后仍能保持一致

7.2 值对象

  • 一般来说不需要有业务含义的唯一标识符,因为我们并不关心它是谁

  • 值对象和实体是整体

  • 值对象是不变的,可共享

  • 值对象复制

    • Java clone

7.3 服务

  • 行为接口

7.4 领域对象生命周期

7.5 聚合

  • 一组相关联的对象,出于数据变化的目的,将它们视为一个单元

    • 汽车中:轮胎+车架+座椅
    • 汽车中:引擎
    • 汽车中:驾驶员+乘客
  • 聚合中的不变性

    • 划出不变性和可变部分

7.6 工厂

  • 工厂用来封装对象创建所必需的知识,它们对创建聚合特别有用

    • 抽象工厂
    • 工厂方法
  • 属于领域层

7.7 组合

  • Hibernate O/R Mapping框架,实现对象的创建和组合

7.8 客户端只关心模型,而不是数据存储,存储和访问都交给Repository完成,避免数据库规范扰乱模型的整洁

限界上下文

  • 确定语义所在的领域边界,边界定义了模型的适用范围,使团队所有成员能够明确地知道什么应该在模型中实现,不应该在模型中实现

7.9 4种Robbin领域模型

  • 失血模式-不提倡

    • POJO 仅有Getter/Setter方法
    • 业务逻辑和应用逻辑,都在应用层
  • 贫血模式

    • 部分业务逻辑放在domain object中
  • 充血模式

    • 大部分业务逻辑放在domain object中
  • 胀血模式-不提倡

    • 过多业务逻辑放在domain object中
  • 实体本之行为放入实体,行为跨越实体本身生命周期的,可放入服务中

八、领域服务

8.1 对一个聚合的操作,放在一个单独的接口中

8.2 CRUD是服务吗

  • 管理行为,是服务

8.3 领域层服务

  • 与业务有关,CRUD

8.4 应用层服务

  • 与软件设计有关,类似MVC中的Controller

8.5 基础层服务

  • 发送Email

九、领域事件

9.1 对聚合的操作,建成一系列离散事件

9.2 在不同场景下,由实体发出事件驱动服务,通过类似异步消息机制实现松耦合

9.3 业务规则 Specification

  • JPA进行条件筛选的时候,有Specification+仓储(Repository)的结合

十、事件风暴

10.1 构建领域模型的充满乐趣的实施方法

10.2 领域时间与架构设计的本质

  • 领域事件

10.3 事件风暴步骤

  • 头脑风暴
  • 罗列领域事件
  • 领域事件集合
  • 标注事件命令
  • 标注时间命令发起方角色
  • 领域故事分析
  • 提取领域对象
  • 领域对象与代码模型映射
  • 代码落地

十一、CQRS框架

11.1 命令与查询分析,数据查询与业务操作分离

11.2 是DDD开发风格下对领域模型按机构的一种简化改造

11.3 DDD+CQRS使用六边形对称性架构

11.4 DDD+CQRS+Event Souring 是有趣且强大的技术

十二、JiveJdon框架

12.1 JiveJdon 3.0是按照2004年国外最新设计思想"领域驱动设计"(Domain-Driven Design 简称DDD)、基于JdonFramework自主开发的复杂软件系统

12.2 开源

12.3 性能优异、可伸缩性强

12.4 可拓展性

12.5 采用组件动态设计的面向构件架构

十三、微服务框架

13.1 微服务的特征

  • 通过服务进行组件化
  • 围绕业务能力组织
  • 去中心化的治理技术
  • 去中心化的管理数据
  • 基础设施自动化
  • 容错和演进式设计

13.2 设计微服务的路径依赖困境

  • 利用拆分单体服务思维,拆分子模块,形成微服务,不可行

13.3 基于微服务的重构

  • 识别领域对象
  • 界定上下文边界
  • 使用聚合概念把关联性强的业务划分在同一个边界下
  • 限定聚合和聚合之间通过聚合根来访问
  • 结合业务限定上下文与技术因素,对服务的粒度、分层、边界划分、依赖关系、集成关系进行梳理
  • 构建通用语言,高效沟通

13.4 微服务设计方法

  • 事件风暴
  • 领域对象以及服务矩阵和代码设计
  • 领域对象以及服务矩阵

13.5 代码结构模型

  • application
  • domain
  • infrastruture
  • interface

13.6 微服务是技术实现和部署的范畴,实现领域或中台的业务逻辑,为前台应用提供服务

十四、分层架构

14.1 MVC框架改造

  • 限定上下文,将一个大领域拆分成独立的子域
  • 针对领域对象,添加领域层,提供服务
  • 用用层,组装各个领域服务,对外提供能力
  • 应用层验证、领域服务验证、领域模型验证

14.2 四层架构

14.3 五层架构

14.4 六边形架构

  • 洋葱架构

十五、更多大厂实践

15.1 阿里盒马

15.2 阿里文娱

15.3 美团外卖

  • 点评业务
  • 供应链业务

15.4 业务中台

  • 中台的本质是提炼各个业务条线的共同需求,并将这些功能打造成组件化产品,然后以 API 接口的形式提供给前台各业务部门使用
  • 从限定上下文到微服务,从应用架构到技术架构
  • 从决策到接口
  • 从领域模型到分层架构
  • 从DDD 到TDD

其他

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

领域驱动设计-Domain-Driven-Design概念 的相关文章

  • Grails 3.x bootRun 失败

    我正在尝试在 grails 3 1 11 中运行一个项目 但出现错误 失败 构建失败并出现异常 什么地方出了错 任务 bootRun 执行失败 进程 命令 C Program Files Java jdk1 8 0 111 bin java
  • Java new Date() 打印

    刚刚学习 Java 我知道这可能听起来很愚蠢 但我不得不问 System out print new Date 我知道参数中的任何内容都会转换为字符串 最终值是 new Date 返回对 Date 对象的引用 那么它是如何打印这个的呢 Mo
  • Play框架运行应用程序问题

    每当我尝试运行使用以下命令创建的新 Web 应用程序时 我都会收到以下错误Play http www playframework org Error occurred during initialization of VM Could no
  • 在 java 类和 android 活动之间传输时音频不清晰

    我有一个android活动 它连接到一个java类并以套接字的形式向它发送数据包 该类接收声音数据包并将它们扔到 PC 扬声器 该代码运行良好 但在 PC 扬声器中播放声音时会出现持续的抖动 中断 安卓活动 public class Sen
  • 制作一个交互式Windows服务

    我希望我的 Java 应用程序成为交互式 Windows 服务 用户登录时具有 GUI 的 Windows 服务 我搜索了这个 我发现这样做的方法是有两个程序 第一个是服务 第二个是 GUI 程序并使它们进行通信 服务将从 GUI 程序获取
  • Android MediaExtractor seek() 对 MP3 音频文件的准确性

    我在使用 Android 时无法在eek 上获得合理的准确度MediaExtractor 对于某些文件 例如this one http www archive org download emma solo librivox emma 01
  • 操作错误不会显示在 JSP 上

    我尝试在 Action 类中添加操作错误并将其打印在 JSP 页面上 当发生异常时 它将进入 catch 块并在控制台中打印 插入异常时出错 请联系管理员 在 catch 块中 我添加了它addActionError 我尝试在jsp页面中打
  • Mockito when().thenReturn 不必要地调用该方法

    我正在研究继承的代码 我编写了一个应该捕获 NullPointerException 的测试 因为它试图从 null 对象调用方法 Test expected NullPointerException class public void c
  • Spring @RequestMapping 带有可选参数

    我的控制器在请求映射中存在可选参数的问题 请查看下面的控制器 GetMapping produces MediaType APPLICATION JSON VALUE public ResponseEntity
  • Java TestNG 与跨多个测试的数据驱动测试

    我正在电子商务平台中测试一系列商店 每个商店都有一系列属性 我正在考虑对其进行自动化测试 是否有可能有一个数据提供者在整个测试套件中提供数据 而不仅仅是 TestNG 中的测试 我尝试不使用 testNG xml 文件作为机制 因为这些属性
  • 如何将 pfx 文件转换为 jks,然后通过使用 wsdl 生成的类来使用它来签署传出的肥皂请求

    我正在寻找一个代码示例 该示例演示如何使用 PFX 证书通过 SSL 访问安全 Web 服务 我有证书及其密码 我首先使用下面提到的命令创建一个 KeyStore 实例 keytool importkeystore destkeystore
  • 为什么HashMap不能保证map的顺序随着时间的推移保持不变

    我在这里阅读有关 Hashmap 和 Hashtable 之间的区别 http javarevisited blogspot sg 2010 10 difference Between hashmap and html http javar
  • 总是使用 Final?

    我读过 将某些东西做成最终的 然后在循环中使用它会带来更好的性能 但这对一切都有好处吗 我有很多地方没有循环 但我将 Final 添加到局部变量中 它会使速度变慢还是仍然很好 还有一些地方我有一个全局变量final 例如android Pa
  • Java Integer CompareTo() - 为什么使用比较与减法?

    我发现java lang Integer实施compareTo方法如下 public int compareTo Integer anotherInteger int thisVal this value int anotherVal an
  • AWS 无法从 START_OBJECT 中反序列化 java.lang.String 实例

    我创建了一个 Lambda 函数 我想在 API 网关的帮助下通过 URL 访问它 我已经把一切都设置好了 我还创建了一个application jsonAPI Gateway 中的正文映射模板如下所示 input input params
  • 仅将 char[] 的一部分复制到 String 中

    我有一个数组 char ch 我的问题如下 如何将 ch 2 到 ch 7 的值合并到字符串中 我想在不循环 char 数组的情况下实现这一点 有什么建议么 感谢您花时间回答我的问题 Use new String value offset
  • Firebase 添加新节点

    如何将这些节点放入用户节点中 并创建另一个节点来存储帖子 我的数据库参考 databaseReference child user getUid setValue userInformations 您需要使用以下代码 databaseRef
  • JGit 检查分支是否已签出

    我正在使用 JGit 开发一个项目 我设法删除了一个分支 但我还想检查该分支是否已签出 我发现了一个变量CheckoutCommand但它是私有的 private boolean isCheckoutIndex return startCo
  • 将 List 转换为 JSON

    Hi guys 有人可以帮助我 如何将我的 HQL 查询结果转换为带有对象列表的 JSON 并通过休息服务获取它 这是我的服务方法 它返回查询结果列表 Override public List
  • Spring Boot @ConfigurationProperties 不从环境中检索属性

    我正在使用 Spring Boot 1 2 1 并尝试创建一个 ConfigurationProperties带有验证的bean 如下所示 package com sampleapp import java net URL import j

随机推荐

  • python读写文本老是报错?codecs模块统一编码 一行代码搞定py字符读写

    在python程序中 经常要用到字符文本的读和写 用py自带的 读read 写write 定义字符编码比较麻烦 而用第三方 codecs 模块 在读写字符文本时 可以指定字符编码 就好用很多 下面 我用 codecs 模块 自己编写了一个d
  • 强化学习笔记-13 Policy Gradient Methods

    强化学习算法主要在于学习最优的决策 到目前为止 我们所讨论的决策选择都是通过价值预估函数来间接选择的 本节讨论的是通过一个参数化决策模型来直接根据状态选择动作 而不是根据价值预估函数来间接选择 我们可以定义如下Policy Gradient
  • 2013电商“三国杀”

    2013电商 三国杀 本周 DCCI发布了 Forecast2013 中国电子商务蓝皮书 蓝皮书预测 2013年 淘宝 京东和腾讯将成为电商三甲 纵观中国电商的2012年 高调的京东 霸气的淘宝和默默耕耘的腾讯 似乎正在勾画着未来中国电商行
  • python time.sleep(t) t为秒

    睡眠5秒 import time time sleep 5
  • location.href 与 location.search

    document location href 返回完整的 URL 如 http www cftea com foo asp p 1 引用 location search是从当前URL的 号开始的字符串 如 http www 51js com
  • 《计算机视觉中的多视图几何》笔记(2)

    2 Projective Geometry and Transformations of 2D 本章主要介绍本书必要的几何知识与符号 文章目录 2 Projective Geometry and Transformations of 2D
  • 元素和小于等于阈值的正方形的最大边长

    LeetCode 1292 元素和小于等于阈值的正方形的最大边长 给你一个大小为 m x n 的矩阵 mat 和一个整数阈值 threshold 请你返回元素总和小于或等于阈值的正方形区域的最大边长 如果没有这样的正方形区域 则返回 0 示
  • QT 信号发送多个参数

    你可以把多个参数包装为一个类发送 实测是可以的
  • DBUS及常用接口介绍

    1 概述 1 1 DBUS概述 DBUS是一种高级的进程间通信机制 DBUS支持进程间一对一和多对多的对等通信 在多对多的通讯时 需要后台进程的角色去分转消息 当一个进程发消息给另外一个进程时 先发消息到后台进程 再通过后台进程将信息转发到
  • Caused by: java.lang.ClassNotFoundException: org.springframework.core.KotlinDetector

    Exception in thread main java lang IllegalArgumentException Cannot instantiate interface org springframework context App
  • win下从NUMA节点分配内存

    微软官网链接 https docs microsoft com zh cn windows win32 memory allocating memory from a numa node redirectedfrom MSDN 示例代码 d
  • Java高级教程

    Java高级教程 Java11文档 Java数据结构 Java工具包提供了强大的数据结构 在Java中的数据结构主要包括以下几种接口和类 枚举 Enumeration 位集合 BitSet 向量 Vector 栈 Stack 字典 Dict
  • Error loading workspace: You are outside of a module and outside of $GOPATH/src. If you are using mo

    1 描述 如果你使用vsCode去编译 go 项目的时候 出现这个错误 那么并不是你的go moudle 除了问题 同时你会发现执行Run Code也是执行失败的 2 原因 你的工作区默认是项目根目录 但你单开的文件并不是项目根目录 3 解
  • lvgl8.2 img 图片显示

    1 lvgl 图片显示源 为了提供良好的图片显示灵活性 所以显示图像的来源可以是以下三种 代码中的一个变量 一个带有像素颜色数据的 C 数组 存储在外部的文件 比如 SD 卡 带有符号的文本 2 内部图片 对于源码内部图片 将图片转换为图片
  • 前端自动化测试——vue单元测试vue-test-utils

    自动化测试分类 单元测试 单元测试 unit testing 是指对软件中的最小可测试单元进行检查和验证 简单来说 单元就是人为规定的最小的被测功能模块 可能是一个单一函数或方法 一个完整的组件或类 单元测试是最小巧也是最简单的测试 它们通
  • paddlelite编译python版: FIND_PACKAGE called with invalid argument或者fatal: no tag exactly matches 。【已解决】

    报错1 不是这个原因 这个错误不会影像编译 fatal no tag exactly matches 518238f89e84868d666b5cbe6860788934f290d7 tag branch develop commit 51
  • TCP flag注释

    http blog csdn net wisage article details 6049733 三次握手Three way Handshake 一个虚拟连接的建立是通过三次握手来实现的 1 B gt SYN gt A 假如服务器A和客户
  • 【华为OD机试】寻找相同子串(C++ Python Java)2023 B卷

    时间限制 C C 1秒 其他语言 2秒 空间限制 C C 262144K 其他语言524288K 64bit IO Format lld 语言限定 C clang11 C clang 11 Pascal fpc 3 0 2 Java jav
  • 若依系统(Ruoyi-Vue)去除redis数据库

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 目的 一 去除redis 配置 二 去除ruoyi framework下RedisConfig的配置 三 在ruoyi common的core redis下新建My
  • 领域驱动设计-Domain-Driven-Design概念

    2021了 你应该要了解DDD了 不然领导和你吹牛你都听不懂 或者你都没法和别人吹牛了 一 Evans DDD 是什么 1 1 背景 2002年 敏捷宣言诞生 时代处于 CS 到 BS 的转换时期 2003年 Eric Evans 发表 l