MASA Framework - DDD设计(1)
目录
MASA Framework - 整体设计思路
MASA Framework - EventBus设计
MASA Framework - MASA Framework - DDD设计(1)
DDD
领域驱动设计是一个有关软件开发的方法论,它提出基于领域开发的开发模式,基于DDD理论,我们可以设计出高质量的软件模型。
它围绕业务概念构建领域模型来控制业务的复杂度,解决软件难以理解和演化的问题。
微服务
微服务是一种架构风格,通过进程间通讯、容错和故障隔离等方式,实现去中心化的服务治理。
DDD与微服务
它们都是高内聚、低耦合,从业务视角分离复杂度,提高响应能力。
高内聚:把相关的业务聚集在一起
低耦合:把关联性较低的拆分为独立的服务
使用DDD搭建微服务我们将获得以下优势:
- 设计清晰,规范
- 基于领域模型,有利于领域知识的传递和传承
- 帮助团队建立良好的沟通
- 协助系统架构的演进
- 提高团队的设计能力(面向对象,架构)
设计
领域设计涉及技术与业务,如何让它们协作起来呢?
战略设计(业务)
领域、子域、限界上下文
- 将领域拆分成子域,并划分核心子域、支撑子域和通用子域
- 以子域展开事件风暴,根据上下文语义划分限界上下文,建立通用语言,完成领域建模
- 领域建模将作为能力中心规划的重要依据
- 完成能力中心地图和优先级后,作为微服务设计的输入完成战术设计
战术设计(技术)
聚合、聚合根、实体、值对象、领域服务等
按照领域模型完成微服务设计和落地
建立聚合、聚合根、实体、值对象、领域服务等对象之间的依赖关系,以代码对象的形式映射到服务中,采用分层架构完成微服务设计和落地
分层架构可以采用Clean Architecture
DDD实践过程
我们将通过DDD + Clean Architecture完成业务与技术的完整落地
统一语言(战略设计)
统一:
- 领域模型术语
- DDD模式名称
技术:
- 技术设计术语
- 技术术语
- 技术设计模式
业务:
- 领域模型术语
- DDD模式名称
- 业务术语
- 设计无关的业务术语

事件风暴(战略设计)
Event Storming时一种领域建模的实践,可以让领域相关人员快速理解业务模型
完整流程包括如统一语言、提出领域事件、规则、命令、读模型、角色、划分子域、票选、补充商机与价值等,
接下来我们先精简一点步骤
活动准备
人:业务人员,领域专家,技术人员,架构师,测试等
看板:可以将事件流可视化的白板或者画图工具等
彩色贴纸:填写事件,命令等
业务场景
规定业务场景,下面我以一个电商项目为例
事件风暴结果

命令风暴结果

寻找聚合
聚合:一组相关领域模型的集合,尽量保证封装业务的不变性,确保关联关系紧密的领域模型内聚
- 按事件顺序依次分析三个问题
- 事件改变的领域模型是什么
- 领域模型是否可以独立访问,是就是聚合
- 不能独立访问,需要通过哪个领域模型(聚合)来访问,将其放到对应聚合内
- 命令贴在聚合左边代表输入,事件贴到聚合右边代表输出
- 检验是否符合聚合规则,不匹配的重新调整聚合
聚合结果
寻找聚合过程中可能会因为业务衔接产生新的输入命令,以虚线表示

划分限界上下文
限界上下文:某个场景或环境下的业务边界
- 基于聚合和领域模型,判断它们要解决的业务问题,如果是同一个问题则放到一个限界上下文中,否则就拆分
- 如果一个聚合同时解决多个问题,则需要对聚合进行拆分,将拆分后的聚合划分到不同的限界上下文
- 解决的业务问题大小(变化原因,内在逻辑等)需与领域专家共同完成
限界上下文结果

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

子域
一个业务领域或子域是一个业务范围。一个业务领域或子域可以包括多个业务能力,一个业务能力对应一个服务。
核心子域指业务成功的主要促成因素,是企业的核心竞争力。
通用子域被整个业务系统使用。
支撑子域是完成业务的必要能力,但不是成功的因素。
除了上面限界上下文结果中标注的子域外,还可以扩展出财务,市场,采购等子域
领域对象关系(战术设计)
分解聚合,提取该聚合包含的领域对象
- 领域对象的业务不变性
- 领域对象具有一致的生命周期

定义实体与值对象(战术设计)
实体:存在唯一性标识,实体间是否相等的判断依据也是唯一标识
值对象:表示属性的不变值
以订单聚合为例:
- 订单聚合包含订单实体,订单行实体
- 订单实体包含收货地址值对象
架构设计
我们简单的把架构设计看作是三个层面:
业务架构:根据业务需求设计业务模块及其关系
DDD的领域建模其实就已经协助我们做了业务架构和系统架构
系统架构:设计系统与子系统的模块及其关系
在DDD中业务架构是可以直接映射到系统架构上的
业务变化会演变为系统架构变化,影响到技术架构变化
技术架构:设计技术和框架细节
技术架构(微服务)则解决子系统之间的解耦,去中心化的服务治理和数据治理
Clean Architecture
寻找聚合时我们提到过输入和输出。而Clean Architecture与DDD集合后就非常适合作为采用DDD方法论的架构落地指导
为了更好的落地读模型设计(查询业务比较往往占八成以上),搭配CQRS可能是个不错的选择。
CQRS优势在于职责分离,提高系统性能、可扩展性、安全性等。也可以从数据驱动转为事件驱动。
要了解CQRS可以看第二篇 MASA Framework - EventBus设计
示例可以参考MASA EShop源码:https://github.com/masalabs/MASA.EShop
除了DDD以外,我们还提供了EventBus、Dapr、CQRS等多种实现方式

老系统演进
绞杀者模式
在现有系统外围将新功能用新的方式构建为新的服务的策略,通过将新功能做成微服务方式,而不是直接修改原有系统,逐步的实现对老系统替换。采用这种策略,随着时间的推移,新的服务就会逐渐“绞杀”老的系统。对于那些规模很大而又难以对现有架构进行修改的遗留系统,推荐采用绞杀者模式。
缺点:可能需要一段时间同时维护两个或以上的项目
修缮模式
修缮者模式就如修房或修路一样,将老旧待修缮的部分进行隔离,用新的方式对其进行单独修复。修复的同时,需保证与其他部分仍能协同功能。从这种思路出发,修缮者模式更多表现为一种重构技术。
DDD实践流程

总结
DDD虽然需要一定的学习成本,但掌握后既可以设计复杂的工程,也可以适当的缩减流程,在小型项目中直接以领域和聚合快速抽象领域模型,配合自己习惯的技术手段(如论是DB First还是Code First)来加强对系统设计的掌控力。
第一篇主要讲解DDD在团队中如何落地,而第二篇则是站在开发的角度如何落地。
学以致用,学无止境。
参考:
AWS领域驱动设计最佳实践
领域驱动设计在互联网业务开发中的实践:https://tech.meituan.com/2017/12/22/ddd-in-practice.html
开源地址
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,欢迎联系我们

MASA Framework - DDD设计(1)的更多相关文章
- MASA Framework - DDD设计(2)
目录 MASA Framework - 整体设计思路 MASA Framework - EventBus设计 MASA Framework - MASA Framework - DDD设计(1) MA ...
- MASA Framework - EventBus设计
目录 MASA Framework - 整体设计思路 MASA Framework - EventBus设计 概述 利用发布订阅模式来解耦不同架构层级,亦可用于解决隔离业务之间的交互 优点: 松耦合 ...
- MASA Framework - 整体设计思路
源起 年初我们在找一款框架,希望它有如下几个特点: 学习成本低 只需要学.Net每年主推的技术栈和业务特性必须支持的中间件,给开发同学减负,只需要专注业务就好 个人见解:一款好用的框架应该是补充,而不 ...
- MASA Framework -- EventBus入门与设计
概述 事件总线是一种事件发布/订阅结构,通过发布订阅模式可以解耦不同架构层级,同样它也可以来解决业务之间的耦合,它有以下优点 松耦合 横切关注点 可测试性 事件驱动 发布订阅模式 通过下图我们可以快速 ...
- 领域驱动(DDD)设计和开发实战
领域驱动设计(DDD)的中心内容是如何将业务领域概念映射到软件工件中.大部分关于此主题的著作和文章都以 Eric Evans 的书<领域驱动设计>为基础,主要从概念和设计的角度探讨领域建模 ...
- MASA Auth - 权限设计
权限术语 Subject:用户,用户组 Action:对Object的操作,如增删改查等 Object:权限作用的对象,也可以理解为资源 Effect:规则的作用,如允许,拒绝 Condition:生 ...
- 如何一步一步用DDD设计一个电商网站(九)—— 小心陷入值对象持久化的坑
阅读目录 前言 场景1的思考 场景2的思考 避坑方式 实践 结语 一.前言 在上一篇中(如何一步一步用DDD设计一个电商网站(八)—— 会员价的集成),有一行注释的代码: public interfa ...
- 如何一步一步用DDD设计一个电商网站(八)—— 会员价的集成
阅读目录 前言 建模 实现 结语 一.前言 前面几篇已经实现了一个基本的购买+售价计算的过程,这次再让售价丰满一些,增加一个会员价的概念.会员价在现在的主流电商中,是一个不大常见的模式,其带来的问题是 ...
- 如何一步一步用DDD设计一个电商网站(十)—— 一个完整的购物车
阅读目录 前言 回顾 梳理 实现 结语 一.前言 之前的文章中已经涉及到了购买商品加入购物车,购物车内购物项的金额计算等功能.本篇准备把剩下的购物车的基本概念一次处理完. 二.回顾 在动手之前我对之 ...
随机推荐
- docker的无用镜像
dangling images build 自己的 docker 镜像的时候,有时会遇到用一个甚至多个中间层镜像,这会一定程度上减少最终打包出来 docker 镜像的大小,但是会产生一些tag 为 n ...
- [ vue ] 监听v-model数据的变化,只要有变化就改变vuex的state值
场景描述: 1. 注册弹出框是用 v-model 绑定数据 showRegisterModal 实现的,点击遮罩层框架会把 showRegisterModal=false 2.REGISTER按 ...
- atroot 的个人博客
我的个人博客 左上角 MENU 打开导航菜单! 向下滚动查看内容! 为啥我要坚持更新博客 周围有很多小伙伴在问,你写博客会有人看嘛?如果没人看,那岂不是写的就没有意义了吗? 这个问题也一度让我陷入是否 ...
- 51 Nod 1083 矩阵取数问题(动态规划)
原题链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1083 题目分析:通过读题发现我们只能往右边或者下边走,意味着 ...
- springBoot--01--快速入门
笔记源码:https://gitee.com/ytfsL/springboot 1.1 原有Spring优缺点分析 1.1.1 Spring的优点分析 Spring是Java企业版(Java Ente ...
- synchronized锁升级详细过程
java对象头由3部分组成: 1.Mark Word 2.指向类对象(对象的class对象)的指针 3.数组长度(数组类型才有) 重点是 Mark Word结构,下面以32位HotSpot为例: 一. ...
- Windows和Linux(Centos7)下安装Nginx
安装Nginx 这篇记录只不过做了一个简单总结,如果对这块没什么概念的话可以看一下知乎的这篇文章 https://zhuanlan.zhihu.com/p/83890573 window下安装 win ...
- JSF/SpringMVC/Struts2区别与比较
转自SpringMVC与Struts2区别与比较总结 1.Struts2是类级别的拦截, 一个类对应一个request上下文,SpringMVC是方法级别的拦截,一个方法对应一个request上下文, ...
- vue3源码node的问题
下载vue3源码后,下载依赖时,node的版本需要在10.0.0以上,并且不同的vue3里面的插件的配置对版本依赖还不同,14.0.0以上的版本基本都不支持win7了, win7系统可以安装12.0. ...
- K8s 资源配额管理对象 ResourcesQuota
Kubernetes 是一个多租户平台,更是一个镜像集群管理工具.一个 Kubernetes 集群中的资源一般是由多个团队共享的,这时候经常要考虑的是如何对这个整体资源进行分配.在 kubernete ...