实现领域驱动设计----第一章

2023-11-01

带着问题上路

  • 什么是领域驱动设计(是什么)
  • 为什么要做领域驱动设计(为什么要做)
  • 怎样做领域驱动设计(怎样做)
  • 其他的设计模式与领域驱动设计的区别(有类似为什么要做,但是是在取长补短的总结)

译者序

就像在20世纪六七十年代出现了软件危机之后,面向对象成为了人们的救赎;瀑布式开发过程遇到瓶颈时,敏捷被搬上了舞台。

读到这想到了本科课程中《软件开发》,第一次接触到了瀑布模型,而后研究生课程中《现代软件开发》,知道了管理程序员也不是件易事,要做代码估算,要做时间估算,要做质量评估。

如何使用本书

DDD总览
通用语言作用于某个限界上下文,它对于领域建模时非常重要的,不管你是在战术上还是战略上设计软件模型,你都应该保证:在一个特定的限界上下文中只使用一套通用语言,并且保证它的清晰性和简洁性。

战略建模
限界上下文是一种概念上的边界,领域模型便工作于其中。同时,限界上下文为通用语言提供了一套环境,项目成员便通过通用语言来表达软件模型。

在战略设计的过程中,你将发现上下文映射图是非常有用的。你的团队将使用上下文映射图来理解姓名的范围。

架构
一种能够支撑限界上下文的架构是六边形(Hexagonal)架构,它可以辅助其他架构风格,比如面向服务架构、REST和时间驱动(Event-Driven)等。

战术建模
我们在限界上下文中进行DDD的战术建模。战术设计的一个重要模式是聚合。
聚合可以由单个实体组成,也可以由一组实体和值对象组成,此时我们必循在聚合的整个生命周期中保证事务上的一致性。

聚合实列通过资源库进行持久化,另外,对聚合的查找和获取也通过资源库完成。
在这里插入图片描述


我们通常忽略了模块,但是正确地设计模块同样是重要的。简单来讲,我们可以将模块看成是Java中的包或C#中的命名空间。如果只是机械式地设计模块,而不是根据通用语言,那么我们将得不偿失。模块中包含的领域对象应该是内聚在一起的。
在这里插入图片描述

第一章DDD入门

本章学习路线图

  • 了解DDD可以为你的项目和团队带来哪些好处
  • 如何确定你的项目是否适合采用DDD
  • 了解DDD的常见替代方案和它们将导致问题的原因
  • 学习DDD的基础
  • 学习如何向你的管理层,领域专家和技术成员推销DDD
  • 了解使用DDD时所面临的挑战
  • 看看一个正在学习采用DDD的团队时如何工作的

什么时领域模型?
领域模型时关于某个特定业务领域的软件模型。通常,领域模型通过对象模型来实现,这些对象同时包含了数据和行为,并且表达了准确的业务含义。

为什么我们需要DDD

  • 使领域专家和开发者在一起工作,这样开发出来的软件能够准确地传达业务规则。当然,对于领域专家和开发者来说,这并不表示单单地包容对方,而是将他们组成一个密切协作地团队。
  • “准确传达业务规则”地意思是说,此时地软件就像如果领域专家是人员时所开发出来地一样。
  • 可以帮助业务人员自我提高。没有任何一个领域专家或者管理者敢说他对业务已经了如指掌了,业务知识也需要一个长期地学习过程。在DDD中,每个人都在学习,同时每个人又是知识地贡献者。
  • 关键在于对知识地集中,因为这样可以确保软件知识并不只是掌握在少数人手中。
  • 在领域专家,开发者和软件本身之间不存在“翻译”,意思是当大家都使用相同地语言进行交流时,每人都能听懂他人所说的。
  • 设计就是代码,代码就是设计。设计是关于软件如何工作的,最好的编码设计来自于多次试验,这得益于敏捷的发现过程。
  • DDD同时提供了战略设计和战术设计两种方式。战略设计帮助我们理解哪些投入是最重要的;哪些既有软件资产是可以重新拿来使用的;哪些人应该被加到团队中?战术设计则帮助我们创建DDD模型中各个部件。



    贫血领域对象是不好的,因为你花了很大的成本来开发领域对象,但是从中却收益甚少。比如,由于存在对象-关系阻抗失配(Object-Relational Impedance),开发者需要将很多时间花在对象和数据存储之间的映射上。这样的代价太大,而收益太小。这样的领域对象根本就不是领域对象,而只是将关系型数据库中的模型映射到了对象上而已。这样的领域对象更像是活动记录(Active Record),此时你可以对架构做个简化,然后使用事务脚本进行开发。

为什么会有贫血领域对象

其中一个原因是:贫血领域对象反映了一种自然的过程式编程风格,但我并不认为这是首要原因。软件业中有很多开发者都是学着示例代码做开发的,这并不是什么坏事,只要示例代码本身是好的。然而,通常情况是,示例代码只是用尽可能简单的方式来展示某个特定的概念或者API特性,而并不强调要遵循多好的设计原则。一些极度简化的示例代码总是包含了大量的getter和setter,于是这些getter和setter随着示例代码每天被程序员原封不动地来回复制。

我们一般的Dao模式存在的问题

  1. saveCustomer()业务意图不明确
  2. 方法的实现本身增加了潜在的复杂性
  3. Customer领域对象根本就不是对象,而只是一个数据持有器(data holder)

如何使用DDD

通用语言和限界上下文同时构成了DDD的两大支柱,并且它们是相辅相成的。

上下文术语
可以将限界上下文看成是整个应用程序之内的一个概念性边界。这个边界之内的每种领域术语、词组或句子----也即通用语言,都有确定的上下文含义。

通用语言
是团队共享的语言。领域专家和开发者使用相同的通用语言进行交流。事实上,团队中每个人都使用相同的通用语言。不管你在团队中的角色如何,只要你是团队的一员,你都将使用通用语言。

使用了领域对象的行为,这种行为表示出了领域中的通用语言:

public class BacklogItem extends Entity{
	private SprintId sprintId;
	private BacklogItemStatusType status;
	...
	public void commitTo(Sprint aSprint){
		if(!this.isScheduledForRekease()){
			throw new IllegalStateException(
				"Must be scheduled for release to commit to sprint.");
				}
		if(this.isCommottedToSprint()){
			if(!aSprint.sprintId().equals(this.sprintId())){
				this.uncommitFromSprint();
			}
		}
		this.elevateStatusWith(BacklogItemStatus.COMMOTTED);
		this.setSprintId(aSprint.sprintId());
		DomainEventPublisher
							.instance()
							.publish(new BacklogItemCommitted(
								this.tenant(),
								this.backlogItemId(),
								this.sprintId()));
	}
	...
}											

此时客户端的代码

//客户端同特定于领域的行为将BacklogItem提交到Sprint中
backlogItem.commitTo(sprint);

以上的代码将行为暴露给客户,行为方法的名字清楚地表明了业务含义。这个领域的专家在建模时讨论了以下需求:

允许将每一个待定项提交到冲刺中。只有在一个待定项位于发布计划(Release)中时才能进行提交。如果一个待定项已经提交到了另外一个冲刺中,那么需要先将其回收。提交完成时,通知相关客户方。

DDD并不笨重
DDD能够很好地与敏捷项目框架结合起来,比如Scrum。DDD也倾向“测试先行,逐步改进”地设计思路。在你开发一个新的领域对象时,比如实体或值对象,你可以采用以下步骤进行:

  1. 编写测试代码以模拟客户代码时如何使用该领域对象地。
  2. 创建该领域对象以使测试代码能够编译通过。
  3. 同时对测试和领域对象进行重构,直到测试代码能够正确地模拟客户代码,同时领域对象拥有能够表明业务行为地方法签名。
  4. 实现领域对象地行为,直到测试通过为止,再对实现代码进行重构。
  5. 向你地团队成员展示代码,包括领域专家,以保证领域对象能够正确地反映通用语言。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

实现领域驱动设计----第一章 的相关文章

  • 二叉搜索树的概念 及 功能代码实现

    1 概念 二叉搜索树 又称 二叉排序树 特点 二叉树 每个节点中保存关键字 key 关键字需要具备 比较 的能力 每个节点 都是 大于左子树 小于右子树 二叉树搜索树中 不会出现 相等的 key 中序遍历 一定是 有序的 时间复杂度 最好和
  • 利用Hbuilder将Vue项目打包成apk

    一 配置config index js 本人没有配置index js文件 就开始进行了打包 结果最终效果是页面空白 解决了空白 接着底部图标 我是用的阿里巴巴图片 资源找不到 所以配置这步比较重要 1 页面空白的解决 打开config in
  • uboot2014移植到QT2440

    http bbs chinaunix net thread 4143968 1 1 html
  • Kotlin 协程(Coroutines)配合使用 Retrofit,网络请求

    第一步 添加所需依赖 管理生命周期 implementation androidx lifecycle lifecycle livedata ktx 2 2 0 implementation androidx lifecycle lifec
  • K-近邻法(KNN算法)

    1 kNN算法 K 最近邻 k Nearest Neighbors 描述 简单地说 k 近邻算法采用测量不同特征值之间的距离方法进行分类 k 近邻算法 是一种基本 分类与回归 方法 它是是 监督学习 中分类方法的一种 属于 懒散学习法 惰性
  • 【实验四】【使用Select 语句查询数据】

    文章目录 数据 一 简单查询 二 汇总查询 三 连接查询和子查询 数据 这里为了体现查询语句的效果 下面根据查询语句的要求设计数据 结果如下 KC表 XSQK表 XS KC表 打开 SQL Server Management Studio
  • 【数据结构与算法】--二叉树OJ题

    单值二叉树 如果二叉树每个节点都具有相同的值 那么该二叉树就是单值二叉树 只有给定的树是单值二叉树时 才返回 true 否则返回 false 示例 1 输入 1 1 1 1 1 null 1 输出 true 示例 2 输入 2 2 2 5
  • 【C语言技巧】滑动滤波算法滤除抖动

    简易滑动滤波算法 算法原理 将新数据放入到数组的最后 每次在得到数据之前先将数据左移一个元素 踢掉第一个元素最旧的数据 最后数组计算平均 include
  • 解决adb push时出现的“Read-only file system“问题

    出现Read only file system问题 不是因为文件或者文件夹的权限不对 而是要push的目录对应的分区是以只读方式挂载的 网上给出的解决办法是重新以读写方式挂载对应分区 以 system分区为例 使用命令 mount o re
  • 手写数字识别画板前后端实现

    1 系统概要 手写数字识别画板系统 按照MVC原则开发 主要由两部分组成 交互界面 视图View 部分是传统的HTML CSS JS网页 这同样也是一种遵循MVC开发方式 手写数字识别部分 模型Model 是使用Python开发的深度学习的
  • 【网络原理】传输层重点协议 TCP与UDP协议详解

    文章目录 一 UDP协议 1 UDP特点 2 UDP协议报文格式 3 基于UDP的应用层协议 4 关于UDP协议的一个拓展问题 经典面试题 二 TCP协议 1 TCP协议报文格式 2 TCP原理 1 确认应答机制 安全机制 2 超时重传机制
  • 【C++STL】快速排序算法(sort)的原理与使用

    一 sort算法原理 std sort 是 C 标准库中提供的排序算法 它使用的是一种经典的排序算法 快速排序 Quicksort 或者是其变种 快速排序是一种基于比较的排序算法 通过不断地选择一个基准值 pivot 将待排序序列分割为两个
  • 做好参加蓝桥杯省赛的准备

    1 选择方向 在除此选择要参加蓝桥杯的方向时是刚学完Java程序设计 对Java产生了比较大的兴趣 也觉得Java是一个特别灵活好用的语言 特别是eclipse的强大快捷键和找错功能使得编程快了很多 也有部分原因是因为C 好长时间没用 都快
  • android oaid

    Oaid获取接入流程 移动智能设备标识公共服务平台 AndroidID IMEI OAID获取 oaid sdk 1 1 0的aar 随着Google对隐私的重视以及Android10的逐渐普及 获取设备的唯一标识越来越来难 在Androi
  • python爬取豆瓣电影并分析_爬取豆瓣电影top250提取电影分类进行数据分析

    标签 空格分隔 python爬虫 一 爬取网页 获取需要内容 我们今天要爬取的是豆瓣电影top250 页面如下所示 我们需要的是里面的电影分类 通过查看源代码观察可以分析出我们需要的东西 直接进入主题吧 知道我们需要的内容在哪里了 接下来就
  • echarts实现横向柱图文字在柱图上面

    前言 echarts实现横向柱图文字在柱图上面 效果图 实现源代码 div style width 100 height 800px div
  • Immer编写简洁的更新state逻辑

    react官网推荐库use immer https www npmjs com package use immer 引入 import useImmer from use immer 优点 简化代码 只需要关注需要变动的部分 而 immer
  • python 使用sys.setdefaultencoding(‘utf-8‘) 显示中文(中文默认会乱码)

    正常情况下 我们在使用python做页面开发时 防止中文出现乱码问题 python2 情况下会使用 如下语句 import sys reload sys sys setdefaultencoding utf 8 但在python3下 报错

随机推荐

  • linux安装nodejs_Ubuntu 18.04 Linux上安装Etherpad,基于Web的实时协作编辑器

    介绍 Etherpad是一个开源的 基于Web的实时协作编辑器 它允许多个人使用他们的Web浏览器同时编辑文档 它还提供了一些很酷的功能 如富文本格式和即时消息 目标是在Ubuntu 18 04 Linux上安装Etherpad 约定 要求
  • vmwre15.5.1安装mac遇到的问题以及解决方法和相应工具

    虚拟键15 5 1 mac cdr文件 百度都是 注意版本 破解vmware没有apple操作系统选项 unlock工具 链接 https pan baidu com s 1tE91r3eCG3Swg3FDi VZ8A 提取码 d54g 放
  • ubuntu22安装和卸载nvidia驱动

    一 安装nvidia驱动 查看可以安装的版本 ubuntu drivers devices 选择安装nvidia driver 515 sudo apt install nvidia driver 515 重启 sudo reboot 验证
  • 服务器系统兼容性问题,微软表示因兼容性问题,部分用户无法升到Windows10最新版本...

    微软已警告Windows 10用户 由于英特尔Thunderbolt NVMe SSD的兼容性问题 他们可能被禁止升级到Windows 10版本2004或20H2 每当Microsoft发布新功能更新时 即使是次要功能更新 例如Window
  • SpringBoot3集成Kafka

    标签 Kafka3 Kafka eagle3 一 简介 Kafka是一个开源的分布式事件流平台 常被用于高性能数据管道 流分析 数据集成和关键任务应用 基于Zookeeper协调的处理平台 也是一种消息系统 具有更好的吞吐量 内置分区 复制
  • 【Vue3】vite打包报错:块的大小超过限制,Some chunks are larger than 500kb after minification

    问题描述 vite打包报错 块的大小超过限制 Some chunks are larger than 500kb after minification 解决方法 1 加大限制的大小将500kb改成1000kb或者更大 chunkSizeWa
  • 2022.6.1 C++——类型设计与实例化对象

    对象的创建与使用 对象的创建与使用 1 直接定义类的实例 对象 2 C 对象模型讨论 3 this指针的作用 对象是类的实例 声明一种数据类型只是告诉编译系统该数据类型的构造 并没有预定内存 类只是一个样板 图纸 以此样板可以在内存中开辟出
  • java 使用jdbc向mysql数据库中插入1亿条数据

    http blog csdn net home zhang article details 50836253 java view plain copy
  • 弱网压测环境 - tcconfig

    弱网压测环境 tcconfig 服务器性能指标 服务器接口的容错机制及重连机制需正常 服务器之间的网络通信需正常 服务器存储数据需一致及准确 请求不发生堆积 数据不发生错乱 弱网指标 带宽 吞吐量 单位时间内传输的数据量 单位通常是 每秒比
  • ROSE笔记-ctf.show_web2-WP

    ctf show web2 WP 直接是一个登录界面 在用户名处输入万能密码 admin or 1 1 显示了登陆信息 现在就是去找回显位置 用order by判断当前查询的列数 order by 4的时候登陆信息消失 而order by
  • 根据Modeller官网教程进行单模板建模

    Tutorial Basic Modeling https salilab org modeller tutorial basic html 1 搜索相关序列 从官网下载源文件 分析 TvLDH ali 存放目标序列 需满足要求的格式 gt
  • 异常处理函数set_exception_handler

    由于历史原因 php一开始被设计为一门面向过程的语言 所以异常处理没有使用像Java一样的 try catch 机制 出错时直接显示到页面上 或者记录到web服务器的错误日志中 并且php的错误分成了很多的级别 例如E ERROR E WA
  • 斐波那契数列(递归改进)

    题目 求斐波那契数列的第n项 写一个函数 输入n 求斐波那契数列的第n项 斐波那契数列的定义如下 大多数人看到后第一时间都会写出如下代码 递归 方法直观但时间效率低 long long Fibonacci unsigned int n if
  • 远程桌面连接不能复制粘贴怎么办 远程控制电脑无法复制粘贴的解决方法

    解决方法如下 第一步 打开远程桌面连接 点开电脑左下角的开始菜单 找到远程桌面连接 点开 如果你不常用远程桌面连接 那么这个图标就在附件里面 仔细找找就看到了 第二步 点开远程桌面连接的对话框 在对话框的左下角找到 显示选项 点开它 第三步
  • 数据加密标准(DES)概念及工作原理

    0x01 数据加密标准DES介绍 数据加密标准 Data Encryption Standard DES 是一种用于加密数字数据的对称密钥算法 密钥长度为56位 安全性不强 但它在密码学的进步中具有很大的影响力 0x02 数据加密标准历史
  • MySQL 锁

    文章目录 1 锁的种类 2 按兼容性划分 1 共享锁 2 排他锁 3 按锁粒度划分 1 表锁 2 行锁 3 注意 4 按锁模式划分 1 记录锁 2 间隙锁 3 临键锁 4 插入意向锁 5 意向锁 5 按加锁机制划分 1 悲观锁 2 乐观锁
  • 支付宝小程序集成mqtt兼容IOS和安卓

    1 前言 去年就想做支付宝小程序接入mqtt协议 但最终多方咨询 问客服问社区得到的答案都是支付宝小程序不能直接支持mqtt协议 偶然间发现徐宏大神的佳作 终于发现了xmqtt js这个好东西 它实现了支付宝小程序完美接入mqtt协议 设备
  • where、having、group by、order by、limit的区别和使用顺序

    where having group by order by limit的区别和使用顺序 姚文斌的博客 CSDN博客
  • 怎么让别人连接自己的数据库(MySQL)

    怎么让别人连接自己的数据库 MySQL update user set host where user root and host localhost flush privileges
  • 实现领域驱动设计----第一章

    带着问题上路 什么是领域驱动设计 是什么 为什么要做领域驱动设计 为什么要做 怎样做领域驱动设计 怎样做 其他的设计模式与领域驱动设计的区别 有类似为什么要做 但是是在取长补短的总结 译者序 就像在20世纪六七十年代出现了软件危机之后 面向