MASA Framework - DDD设计(1)

DDD

领域驱动设计是一个有关软件开发的方法论,它提出基于领域开发的开发模式,基于DDD理论,我们可以设计出高质量的软件模型。

它围绕业务概念构建领域模型来控制业务的复杂度,解决软件难以理解和演化的问题。

微服务

微服务是一种架构风格,通过进程间通讯、容错和故障隔离等方式,实现去中心化的服务治理。

DDD与微服务

它们都是高内聚、低耦合,从业务视角分离复杂度,提高响应能力。

高内聚:把相关的业务聚集在一起

低耦合:把关联性较低的拆分为独立的服务

使用DDD搭建微服务我们将获得以下优势

  • 设计清晰,规范

  • 基于领域模型,有利于领域知识的传递和传承

  • 帮助团队建立良好的沟通

  • 协助系统架构的演进

  • 提高团队的设计能力(面向对象,架构)

设计

领域设计涉及技术与业务,如何让它们协作起来呢?

战略设计(业务)

领域、子域、限界上下文

  • 将领域拆分成子域,并划分核心子域、支撑子域和通用子域

  • 以子域展开事件风暴,根据上下文语义划分限界上下文,建立通用语言,完成领域建模

  • 领域建模将作为能力中心规划的重要依据

  • 完成能力中心地图和优先级后,作为微服务设计的输入完成战术设计

战术设计(技术)

聚合、聚合根、实体、值对象、领域服务等

  • 按照领域模型完成微服务设计和落地

  • 建立聚合、聚合根、实体、值对象、领域服务等对象之间的依赖关系,以代码对象的形式映射到服务中,采用分层架构完成微服务设计和落地

    分层架构可以采用Clean Architecture

DDD实践过程

我们将通过DDD + Clean Architecture完成业务与技术的完整落地

统一语言(战略设计)

统一:

  • 领域模型术语

  • DDD模式名称

技术:

  • 技术设计术语

  • 技术术语

  • 技术设计模式

业务:

  • 领域模型术语

  • DDD模式名称

  • 业务术语

  • 设计无关的业务术语

d78d031545d57519d60fc85b11f00973.png

事件风暴(战略设计)

Event Storming是一种领域建模的实践,可以让领域相关人员快速理解业务模型

完整流程包括如统一语言、提出领域事件、规则、命令、读模型、角色、划分子域、票选、补充商机与价值等,

接下来我们先精简一点步骤

活动准备

人:业务人员,领域专家,技术人员,架构师,测试等

看板:可以将事件流可视化的白板或者画图工具等

彩色贴纸:填写事件,命令等

业务场景

规定业务场景,下面我以一个电商项目为例

事件风暴结果

2c44a1511dfc329aac86da2f8663d7fe.png

命令风暴结果

4f2dba64406c259c8ebcc46b1bc45055.png

寻找聚合

聚合:一组相关领域模型的集合,尽量保证封装业务的不变性,确保关联关系紧密的领域模型内聚

  1. 按事件顺序依次分析三个问题

  • 事件改变的领域模型是什么

  • 领域模型是否可以独立访问,是就是聚合

  • 不能独立访问,需要通过哪个领域模型(聚合)来访问,将其放到对应聚合内

命令贴在聚合左边代表输入,事件贴到聚合右边代表输出

检验是否符合聚合规则,不匹配的重新调整聚合

聚合结果

寻找聚合过程中可能会因为业务衔接产生新的输入命令,以虚线表示

fa7b12671935e0852c2262c1c2640e0e.png

划分限界上下文

限界上下文:某个场景或环境下的业务边界

  1. 基于聚合和领域模型,判断它们要解决的业务问题,如果是同一个问题则放到一个限界上下文中,否则就拆分

  2. 如果一个聚合同时解决多个问题,则需要对聚合进行拆分,将拆分后的聚合划分到不同的限界上下文

  3. 解决的业务问题大小(变化原因,内在逻辑等)需与领域专家共同完成

限界上下文结果

d48248232268077e4ac6b1d8347d1534.png

界限上下文映射

当上下文很多的时候,不同的团队负责不同的上下文,为了保证有效的工作可以定义不同的上下文之间的关系来创建一个所有模型上下文的全局视图。两个上下文之间是有方向的,上游(U或Upstream),下游(D或Downstream)

界限上下文映射结果

638288785aaabecacd23693cd415cc07.png

子域

一个业务领域或子域是一个业务范围。一个业务领域或子域可以包括多个业务能力,一个业务能力对应一个服务。

核心子域指业务成功的主要促成因素,是企业的核心竞争力。

通用子域被整个业务系统使用。

支撑子域是完成业务的必要能力,但不是成功的因素。

除了上面限界上下文结果中标注的子域外,还可以扩展出财务,市场,采购等子域

领域对象关系(战术设计)

分解聚合,提取该聚合包含的领域对象

  • 领域对象的业务不变性

  • 领域对象具有一致的生命周期

779cf69f1c7933f2d7d23db5c16342a4.png

定义实体与值对象(战术设计)

实体:存在唯一性标识,实体间是否相等的判断依据也是唯一标识

值对象:表示属性的不变值

以订单聚合为例:

  • 订单聚合包含订单实体,订单行实体

  • 订单实体包含收货地址值对象

Clean Architecture

寻找聚合时我们提到过输入和输出。而Clean Architecture与DDD集合后就非常适合作为采用DDD方法论的架构落地指导

为了更好的落地读模型设计(查询业务比较往往占八成以上),搭配CQRS可能是个不错的选择。

CQRS优势在于职责分离,提高系统性能、可扩展性、安全性等。也可以从数据驱动转为事件驱动。

要了解CQRS可以看第二篇 MASA Framework - EventBus设计

示例可以参考MASA EShop源码:https://github.com/masalabs/MASA.EShop

除了DDD以外,我们还提供了EventBus、Dapr、CQRS等多种实现方式

69e748b00030667f55d9b6a496cc502d.png

老系统演进

绞杀者模式

在现有系统外围将新功能用新的方式构建为新的服务的策略,通过将新功能做成微服务方式,而不是直接修改原有系统,逐步的实现对老系统替换。采用这种策略,随着时间的推移,新的服务就会逐渐“绞杀”老的系统。对于那些规模很大而又难以对现有架构进行修改的遗留系统,推荐采用绞杀者模式。

缺点:可能需要一段时间同时维护两个或以上的项目

修缮模式

修缮者模式就如修房或修路一样,将老旧待修缮的部分进行隔离,用新的方式对其进行单独修复。修复的同时,需保证与其他部分仍能协同功能。从这种思路出发,修缮者模式更多表现为一种重构技术。

DDD实践流程

fde40cade5a878584ffb9f0272190ba7.png

总结

DDD虽然需要一定的学习成本,但掌握后既可以设计复杂的工程,也可以适当的缩减流程,在小型项目中直接以领域和聚合快速抽象领域模型,配合自己习惯的技术手段(如论是DB First还是Code First)来加强对系统设计的掌控力。

第一篇主要讲解DDD在团队中如何落地,而第二篇则是站在开发的角度如何落地。

学以致用,学无止境。

参考:

AWS领域驱动设计最佳实践

开源地址

MASA.BuildingBlocks:https://github.com/masastack/MASA.BuildingBlocks

MASA.Contrib:https://github.com/masastack/MASA.Contrib

MASA.Utils:https://github.com/masastack/MASA.Utils

MASA.EShop:https://github.com/masalabs/MASA.EShop

MASA.Blazor:https://github.com/BlazorComponent/MASA.Blazor

如果你对我们的 MASA Framework 感兴趣,无论是代码贡献、使用、提 Issue,欢迎联系我们

e509618537dabe2c21a49088255c35d5.png

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

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

相关文章

LeetCode之Reverse String

1、题目: Write a function that takes a string as input and returns the string reversed. Example: Given s "hello", return "olleh". 2、代码实现: 代码实现1:public static String reverseString(String s) {if (s null) {…

linux第二课

linux第二课关机 halt shutdown重启 reboot运行终端 gnome-terminalsystem-config-date 日期与时间firefox http://www.baidu.com 火狐打开百度gedit 文件名 文本编辑器转载于:https://blog.51cto.com/2732951/1899825

mysql的indata文件_【数据分析】MySQL之不能导入本地文件“Loading local data is disable;”...

今天在使用"利用MySQL的命令行进行CSV文件的导入"时,遇到了这样一个问题:提示本地文件无法导入,必须要"同时获得客户端和服务器端的许可"。很难受,于是上网搜了一下教程,最后综合了以下这几个网站…

经典语录和思考总结

研发类  科学研究,搞设计的 技术类  工程技术,搞实施的 管理类  工商管理,人为管理,。。。 功成名就 成功并不是一蹴而就的,成功分为“成”和“功”两个阶段,只有积累“功”,才能促使“成…

Kubernetes 集群日志 和 EFK 架构日志方案

目录第一部分:Kubernetes 日志Node Level Logging AgentStreaming sidecar containerSidecar Logging AgentKubernetes Logging 是如何工作的Kubernetes Pod 日志存储位置Kubelet LogsKubernetes 容器日志格式Kubernetes 日志的类型Kubernetes Logging 架构Kubernet…

Android之EditText自定义边框和边框颜色(转载)

介绍一种比较常见的用法 第一步:准备两张图片大小一样,颜色不同的图片。图片名称分为:editbox_focus.png和editbox_normal.png 放入工程的drawable文件夹下。 第二步:在drawable文件下创建 my_edittext.xml文件 内容如下&#xff…

LeetCode之Hamming Distance

1、题目 The Hamming distance between two integers is the number of positions at which the corresponding bits are different. Given two integers x and y, calculate the Hamming distance. Note: 0 ≤ x, y < 231. Example: Input: x 1, y 4Output: 2Explanation…

python运行速度慢是解释器的原因_python为什么会运行慢

我们之前一定听有人说过&#xff0c;python的执行速度比其他语言慢。python会运行慢的原因&#xff1a;1、python是动态性语言不是静态性语言这是说在python程序执行的时候&#xff0c;编译器不知道变量的类型。图1.展示了C语言中的变量与python中变量的区别。在C中编译器知道变…

HDU1232 畅通工程

问题链接&#xff1a;HDU1232 畅通工程。 问题简述&#xff1a;输入n和m&#xff0c;分别表示城镇的数量和城镇间道路的数量。再输入m个数对s和d表示城镇s到d有道路连通。问还需要修多少条道路才能够把这些城镇都连通起来。 问题分析&#xff1a;这是一个有关图的连通性问题&am…

LeetCode之Keyboard Row

1、题目&#xff1a; Given a List of words, return the words that can be typed using letters of alphabeton only one rows of American keyboard like the image below.Example 1: Input: ["Hello", "Alaska", "Dad", "Peace"]…

微信公众平台多客服

微信公众平台官方推出多客服功能&#xff0c;商户在微信公众平台&#xff08;http://mp.weixin.qq.com&#xff09;开通人工客服权限以后&#xff0c;于“功能-多客服”中&#xff0c;添加客服。然后可以在电脑端上使用多客服接待。其使用方法如下。 1建立客服团队 商户在微信公…

C#中类的异常处理

欢迎您成为我的读者&#xff0c;希望这篇文章能给你一些帮助。前言日常编码过程中&#xff0c;最重要的技能不是说你学会使用很多最新的编程技术或者做出一个高大上的系统。而是你在写代码过程中&#xff0c;对异常的处理&#xff0c;是否系统可以稳定&#xff0c;健壮。对于异…

MongoDB常用操作

1.查看帮助命令 help db.yourColl.help(); db.youColl.find().help(); db.help()&#xff1a;显示数据库操作命令&#xff0c;里面有很多的命令 db.foo.help()&#xff1a;显示集合操作命令&#xff0c;同样有很多的命令&#xff0c;foo指的是当前数据库下&#xff0c;一个叫f…

Linus Torvalds: 成功的项目源于99%的汗水与1%的创新

2017年2月15日&#xff0c;在加利福尼亚州的开源领袖峰会上&#xff0c;由Linux基金会执行董事Jim Zemlin进行的一次采访中&#xff0c;Torvalds讨论了他如何管理Linux内核的开发以及他对工作的态度。\\\\Linus Torvalds认为&#xff0c;科技行业对创新的颂扬是一种自鸣得意&am…

LeetCode之Fizz Buzz

1、题目 Write a program that outputs the string representation of numbers from 1 to n. But for multiples of three it should output “Fizz” instead of the number and for the multiples of five output “Buzz”. For numbers which are multiples of both three a…

Large sum

聪明的办法是想&#xff1a;求前10位&#xff0c;那只要前8位加起来&#xff0c;进2位就OK。 本的办法&#xff0c;就是真的加起来&#xff0c;截前面10位。如我。 numList str.split() sum 0 for i in range(0,len(numList)):sum int(numList[i][0:50])print i,numList[i][…

.NET6之MiniAPI(十六):数据保护

对于web&#xff0c;安全是一个永久的话题&#xff0c;所以ASP.NET Core数据保护提供了一个简单&#xff0c;易用的加密API&#xff0c;可以用来保护数据&#xff0c;密钥管理和轮换。ASP.NET Core的数据保护是根据本机的一个key来生成加密码&#xff0c;然后再用这个key来解密…

linux下安装配置DHCP服务器

前提是已经安装了 core 及 base 两个组 12345# cat /etc/redhat-release Red Hat Enterprise Linux Server release 6.4 (Santiago) # uname -a Linux localhost.localdomain 2.6.32-358.el6.x86_64 #1 SMP Tue Jan 29 11:47:41 EST 2013 x86_64 x86_64 x86_64 GNU/Linux修改…

java ecc 加密_java-信息安全(十一)-非对称加密算法002-ECC,签名003-ECDSA签名

一、概述ECC算法(Elliptic curve cryptography&#xff0c;椭圆曲线密码学)椭圆加密算法(ECC)是一种公钥加密体制&#xff0c;最初由Koblitz和Miller两人于1985年提出&#xff0c;其数学基础是利用椭圆曲线上的有理点构成Abel加法群上椭圆离散对数的计算困难性。是目前已知的公…

网络数据嗅探工具HexInject

网络数据嗅探工具HexInject网络数据嗅探是渗透测试工作的重要组成部分。通过嗅探&#xff0c;渗透人员可以了解足够多的内容。极端情况下&#xff0c;只要通过嗅探&#xff0c;就可以完成整个任务&#xff0c;如嗅探到支持网络登录的管理员帐号和密码。为了实现这个功能&#x…