01.领域驱动设计:微服务设计为什么要选择DDD学习总结

目录

1、前言

2、软件架构模式的演进

3、微服务设计和拆分的困境

4、为什么 DDD适合微服务

5、DDD与微服务的关系

6、总结


1、前言

我们知道,微服务设计过程中往往会面临边界如何划定的问题,不同的人会根据自己对微服务的理

解而拆分出不同的微服务,于是大家各执一词,谁也说服不了谁,都觉得自己很有道理。

那在实际落地过程中,见过不少项目在面临这种微服务设计困惑时,是靠拍脑袋硬完成的,上线后

运维的压力就可想而知了。那是否有合适的理论或设计方法来指导微服务设计呢?有的,就是

领域驱动设计(DDD)

2、软件架构模式的演进

我们知道,这些年来随着设备和新技术的发展,软件的架构模式发生了很大的变化。

软件架构模式大体来说经历了从单机、集中式到分布式微服务架构三个阶段的演进。随着分布式技

术的快速兴起,我们已经进入到了微服务架构时代

我们先来分析一下,软件架构模式演进的三个阶段。

第一阶段是单机架构

采用面向过程的设计方法,系统包括客户端 UI 层和数据库两层,采用 C/S 架构模式,整个系统围

绕数据库驱动设计和开发,并且总是从设计数据库和字段开始。

第二阶段是集中式架构

采用面向对象的设计方法,系统包括业务接入层、业务逻辑层和数据库层,采用经典的三层架构,

也有部分应用采用传统的 SOA 架构。这种架构容易使系统变得臃肿,可扩展性和弹性伸缩性差。

第三阶段是分布式微服务架构

随着微服务架构理念的提出,集中式架构正向分布式微服务架构演进。微服务架构可以很好地实现

应用之间的解耦,解决单体应用扩展性和弹性伸缩能力不足的问题。

我们知道,在单机和集中式架构时代系统分析、设计和开发往往是独立、分阶段割裂进行的

比如,在系统建设过程中,我们经常会看到这样的情形:A 负责提出需求,B 负责需求分析,C 负

责系统设计,D负责代码实现,这样的流程很长,经手的人也很多,很容易导致信息丢失。最后,

就很容易导致需求、设计与代码实现的不一致,往往到了软件上线后,我们才发现很多功能并不是

自己想要的,或者做出来的功能跟自己提出的需求偏差太大。

而且在单机和集中式架构这两种模式下,软件无法快速响应需求和业务的迅速变化,最终错失发展

良机。此时,分布式微服务的出现就有点恰逢其时的意思了。

3、微服务设计和拆分的困境

那进入微服务架构时代以后,微服务确实也解决了原来采用集中式架构的单体应用的很多问题,比

扩展性、弹性伸缩能力、小规模团队的敏捷开发等等。

但在看到这些好处的同时,微服务实践过程中也产生了不少的争论和疑惑:微服务的粒度应该多大

呀?微服务到底应该如何拆分和设计呢?微服务的边界应该在哪里?

可以说,很久以来都没有一套系统的理论和方法可以指导微服务的拆分,包括微服务架构模式的提

出者 Martin Fowler 在提出微服务架构的时候,也没有告诉我们究竟应该如何拆分微服务。

于是,在这段较长的时间里,就有不少人对微服务的理解产生了一些曲解。有人认为:“微服务很

简单,不过就是把原来一个单体包拆分为多个部署包,或者将原来的单体应用架构替换为一套支持

微服务架构的技术框架,就算是微服务了。” 还有人说:“微服务嘛,就是要微要小,拆得越小效

果越好。”

但我想这两年,你在技术圈中一定听说过一些项目因为前期微服务拆分过度,导致项目复杂度过

高,无法上线和运维。

综合来看,我认为微服务拆分困境产生的根本原因就是不知道业务或者微服务的边界到底在什么地

。换句话说,确定了业务边界和应用边界,这个困境也就迎刃而解了。

那如何确定,是否有相关理论或知识体系支持呢?在回答这些问题之前,我们先来了解一下领域驱

动设计与微服务的前世今生。

2004 年埃里克·埃文斯(Eric Evans)发表了《领域驱动设计》(Domain-Driven Design–Tackling

Complexity in the Heart of Software)这本书,从此领域驱动设计(DomainDriven Design,简称

DDD)诞生。DDD核心思想是通过领域驱动设计方法定义领域模型从而确定业务和应用边界,

保证业务模型与代码模型的一致性

但 DDD提出后在软件开发领域一直都是“雷声大,雨点小”!直到 Martin Fowler 提出微服务架构,

DDD才真正迎来了自己的时代。

有些熟悉 DDD设计方法的软件工程师在进行微服务设计时,发现可以利用 DDD设计方法来建立领

域模型,划分领域边界,再根据这些领域边界从业务视角来划分微服务边界。而按照 DDD方法设

计出的微服务的业务和应用边界都非常合理,可以很好地实现微服务内部和外部的“高内聚、低耦

”。于是越来越多的人开始把 DDD作为微服务设计的指导思想。

现在,很多大型互联网企业已经将 DDD设计方法作为微服务的主流设计方法了。DDD也从过去“雷

声大,雨点小”,开始真正火爆起来。

4、为什么 DDD适合微服务

DDD 是一种处理高度复杂领域的设计思想,它试图分离技术实现的复杂性,并围绕业务概念构建

领域模型来控制业务的复杂性,以解决软件难以理解,难以演进的问题。DDD不是架构,而是一

架构设计方法论,它通过边界划分将复杂业务领域简单化,帮我们设计出清晰的领域和应用边

界,可以很容易地实现架构演进。

DDD包括战略设计战术设计两部分。

战略设计主要从业务视角出发,建立业务领域模型,划分领域边界,建立通用语言的限界上下文,

限界上下文可以作为微服务设计的参考边界。

战术设计从技术视角出发侧重于领域模型的技术实现,完成软件开发和落地,包括:聚合根、

实体、值对象、领域服务、应用服务和资源库代码逻辑的设计和实现。

我们来看看 DDD是如何进行战略设计的。

DDD战略设计会建立领域模型,领域模型可以用于指导微服务的设计和拆分事件风暴是建立领

域模型的主要方法,它是一个从发散到收敛的过程。它通常采用用例分析、场景分析和用户旅程分

,尽可能全面不遗漏地分解业务领域,并梳理领域对象之间的关系,这是一个发散的过程。事件

风暴过程会产生很多的实体、命令、事件等领域对象,我们将这些领域对象从不同的维度进行聚

类,形成如聚合、限界上下文等边界,建立领域模型,这就是一个收敛的过程。

我们可以用三步来划定领域模型和微服务的边界。

第一步:在事件风暴中梳理业务过程中的用户操作、事件以及外部依赖关系等,根据这些要素梳理

出领域实体等领域对象。

第二步:根据领域实体之间的业务关联性,将业务紧密相关的实体进行组合形成聚合,同时确定聚

合中的聚合根、值对象和实体。在这个图里,聚合之间的边界是第一层边界,它们在同一个微服务

实例中运行,这个边界是逻辑边界,所以用虚线表示。

第三步:根据业务及语义边界等因素,将一个或者多个聚合划定在一个限界上下文内,形成领域模

。在这个图里,限界上下文之间的边界是第二层边界,这一层边界可能就是未来微服务的边界,

不同限界上下文内的领域逻辑被隔离在不同的微服务实例中运行,物理上相互隔离,所以是物理边

界,边界之间用实线来表示。

有了这两层边界,微服务的设计就不是什么难事了。

战略设计中我们建立了领域模型,划定了业务领域的边界,建立了通用语言和限界上下文,确定

了领域模型中各个领域对象的关系。到这儿,业务端领域模型的设计工作基本就完成了,这个过程

同时也基本确定了应用端的微服务边界。

在从业务模型向微服务落地的过程中,也就是从战略设计向战术设计的实施过程中,我们会将领域

模型中的领域对象与代码模型中的代码对象建立映射关系,将业务架构和系统架构进行绑定。当我

们去响应业务变化调整业务架构和领域模型时,系统架构也会同时发生调整,并同步建立新的映射

关系。

5、DDD与微服务的关系

有了上面的讲解,现在我们再次总结下 DDD与微服务的关系。

DDD是一种架构设计方法,微服务是一种架构风格,两者从本质上都是为了追求高响应力,而从

业务视角去分离应用系统建设复杂度的手段。两者都强调从业务出发,其核心要义是强调根据业务

发展,合理划分领域边界,持续调整现有架构,优化现有代码,以保持架构和代码的生命力,也就

是我们常说的演进式架构。

DDD主要关注:从业务领域视角划分领域边界,构建通用语言进行高效沟通,通过业务抽象,建

立领域模型,维持业务和代码的逻辑一致性。

微服务主要关注:运行时的进程间通信、容错和故障隔离,实现去中心化数据管理和去中心化服务

治理,关注微服务的独立开发、测试、构建和部署

6、总结

今天我们主要学习微服务设计和拆分的难题。通过DDD战略设计可以建立领域模型,划定领域边

界,解决微服务设计过程中,边界难以划定的难题。如果你的业务焦点在领域和领域逻辑,那么你

就可以选择DDD作为微服务的设计方法!

更关键的一点是,DDD不仅可以用于微服务设计,还可以很好地应用于企业中台的设计。

如果你的企业正在做中台转型,DDD将会是一把利器,它可以帮你建立一个非常好的企业级中台

业务模型。有关这点你还会在后面的文章中见到详解。

除此之外,DDD战术设计对设计和开发人员的要求相对较高,实现起来相对复杂。不同企业的研

发管理能力和个人开发水平可能会存在差异。尤其对于传统企业而言,在战术设计落地的过程中,

可能会存在一定挑战和困难,我建议你和你的公司如果有这方面的想法,就一定要谨慎评估自己的

能力,选择最合适的方法落地DDD。

总体来说,DDD可以给你带来以下收获

  1. DDD是一套完整而系统的设计方法,它能带给你从战略设计到战术设计的标准设计过程,使得你的设计思路能够更加清晰,设计过程更加规范。

  2. DDD善于处理与领域相关的拥有高复杂度业务的产品开发,通过它可以建立一个核心而稳定的领域模型,有利于领域知识的传递与传承。

  3. DDD强调团队与领域专家的合作,能够帮助你的团队建立一个沟通良好的氛围,构建一致的架构体系。

  4. DDD的设计思想、原则与模式有助于提高你的架构设计能力

  5. 无论是在新项目中设计微服务,还是将系统从单体架构演进到微服务,都可以遵循DDD的架构原则

  6. DDD不仅适用于微服务,也适用于传统的单体应用。

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

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

相关文章

vue2 事件总线

原图下载:https://download.csdn.net/download/weixin_47401101/88788636

面向Java开发者的ChatGPT提示词工程(11)扩写

什么是扩写? 扩写是指将较短的文本交给GPT生成更长的文本。比如:根据一组基本指令,写出一封完整的电子邮件;或者根据一系列主题,创作出一篇包含这些主题的文章。 这样的技术,有着广阔的应用场景&#xff…

【蒸馏】目标检测蒸馏的不完全整理和个人笔记

其实仔细想想模型蒸馏的监督信号无非来自原先损失函数(分类,bbox)或者是相关组件(backbone,FPN),在这里我不太想用传统的logit蒸馏和feature map蒸馏来表示上面两种蒸馏方式, 主要是…

深入浅出 diffusion(4):pytorch 实现简单 diffusion

1. 训练和采样流程 2. 无条件实现 import torch, time, os import numpy as np import torch.nn as nn import torch.optim as optim from torchvision.datasets import MNIST from torchvision import transforms from torch.utils.data import DataLoader from torchvision.…

LayoutInflater.inflate全面解读

方法解析 LayoutInflater.inflate() 是 Android 系统中用于将 XML 布局文件转换成相应的 View 的方法。在 Android 开发中,我们经常使用此方法来动态创建和填充布局。 public View inflate(LayoutRes int resource, Nullable ViewGroup root, boolean attachToRoo…

LVGL v9学习笔记 | 12 - 弧形控件的使用方法(arc)

一、arc控件 arc控件的API在lvgl/src/widgets/arc/lv_arc.h 中声明,以lv_arc_xxx命名。 arc控件由背景圆弧和前景圆弧组成,前景圆弧的末端有一个旋钮,前景圆弧可以被触摸调节。 1. 创建arc对象 /*** Create an arc object* @param parent pointer to an object, it w…

Pyecharts 风采:从基础到高级,打造炫酷象形柱状图的完整指南【第40篇—python:象形柱状图】

文章目录 引言安装PyechartsPyecharts象形柱状图参数详解1. Bar 类的基本参数2. 自定义图表样式3. 添加标签和提示框 代码实战:绘制多种炫酷象形柱状图进阶技巧:动态数据更新与交互性1. 动态数据更新2. 交互性设计 拓展应用:结合其他图表类型…

深度学习-使用Labelimg数据标注

数据标注是计算机视觉和机器学习项目中至关重要的一步,而使用工具进行标注是提高效率的关键。本文介绍了LabelImg,一款常用的开源图像标注工具。用户可以在图像中方便而准确地标注目标区域,为训练机器学习模型提供高质量的标注数据。LabelImg…

Unity中URP下逐顶点光照

文章目录 前言一、之前额外灯逐像素光照的数据准备好后,还有最后的处理二、额外灯的逐顶点光照1、逐顶点额外灯的光照颜色2、inputData.vertexLighting3、surfaceData.albedo 前言 在上篇文章中,我们分析了Unity中URP下额外灯,逐像素光照中聚…

vue3 codemirror关于 sql 和 json格式化的使用以及深入了解codemirror 使用json格式化提示错误的关键代码

文章目录 需求说明0、安装1. 导入js脚本2.配置3.html处使用4.js处理数据(1)json格式化处理(2)sql格式化处理 5. 解决问题1:json格式化错误提示报错(1)打开官网(2)打开官网&#xff0…

【机器学习笔记】1 线性回归

回归的概念 二分类问题可以用1和0来表示 线性回归(Linear Regression)的概念 是一种通过属性的线性组合来进行预测的线性模型,其目的是找到一条直线或者一个平面或者更高维的超平面,使得预测值与真实值之间的误差最小化&#x…

ppt背景图片怎么设置?让你的演示更加出彩!

PowerPoint是一款广泛应用于演示文稿制作的软件,而背景图片是演示文稿中不可或缺的一部分。一个好的背景图片能够提升演示文稿的整体效果,使观众更加关注你的演示内容。可是ppt背景图片怎么设置呢?本文将介绍ppt背景图片设置的三个方法&#…

数据库 sql select *from account where name=‘张三‘ 执行过程

select *from account where name张三分析上面语句的执行过程 用到了索引 由于是根据 1.name字段进行查询,所以先根据name张三’到name字段的二级索引中进行匹配查 找。但是在二级索引中只能查找到 Arm 对应的主键值 10。 2.由于查询返回的数据是*&#xff0c…

5.Hive表修改Location,一次讲明白

Hive表修改Loction 一、Hive中修改Location语句二、方案1 删表重建1. 创建表,写错误的Location2. 查看Location3. 删表4. 创建表,写正确的Location5. 查看Location 三、方案2 直接修改Location并恢复数据1.建表,指定错误的Location&#xff0…

【CSS】实现鼠标悬停图片放大的几种方法

1.背景图片放大 使用css设置背景图片大小100%&#xff0c;同时设置位置和过渡效果&#xff0c;然后使用&#xff1a;hover设置当鼠标悬停时修改图片大小&#xff0c;实现悬停放大效果。 <!DOCTYPE html> <html lang"en"> <head><meta charset…

###C语言程序设计-----C语言学习(4)#

前言&#xff1a;感谢老铁的浏览&#xff0c;希望老铁可以一键三连加个关注&#xff0c;您的支持和鼓励是我前进的动力&#xff0c;后续会分享更多学习编程的内容。现在开始今天的内容&#xff1a; 一. 主干知识的学习 1.字符型数据 &#xff08;1&#xff09;字符型常量 字…

Leetcode541反转字符串Ⅱ(java实现)

我们今天分享的题目是字符串反转的进阶版反转字符串Ⅱ。 我们首先来看题目描述&#xff1a; 乍一看题目&#xff0c;有种懵逼的感觉&#xff0c;不要慌&#xff0c;博主来带着你分析题目&#xff0c;题目要求&#xff1a; 1. 每隔2k个字符&#xff0c;就对2k字符中的前k个字符…

C++设计模式介绍:优雅编程的艺术

物以类聚 人以群分 文章目录 简介为什么有设计模式&#xff1f; 设计模式七大原则单一职责原则&#xff08;Single Responsibility Principle - SRP&#xff09;开放封闭原则&#xff08;Open/Closed Principle - OCP&#xff09;里氏替换原则&#xff08;Liskov Substitution …

MongoDB:从容器使用到 Mongosh、Python/Node.js 数据操作

文章目录 1. 容器与应用之间的关系介绍2. 使用 Docker 容器安装 MongoDB3. Mongosh 操作3.1 Mongosh 连接到 MongoDB3.2 基础操作与 CRUD 4. Python 操作 MongoDB5. Nodejs 操作 MongoDB参考文献 1. 容器与应用之间的关系介绍 MongoDB 的安装有时候并不是那么容易的&#xff0…

《HelloGitHub》第 94 期

兴趣是最好的老师&#xff0c;HelloGitHub 让你对编程感兴趣&#xff01; 简介 HelloGitHub 分享 GitHub 上有趣、入门级的开源项目。 https://github.com/521xueweihan/HelloGitHub 这里有实战项目、入门教程、黑科技、开源书籍、大厂开源项目等&#xff0c;涵盖多种编程语言 …