# DDD 思想解读及优秀实践
# DDD的背景及来源
DDD的背景和来源
- DDD 的核心思想与解决的痛点
- DDD 的过去,现在与未来
- 面向对象和敏捷与DDD的区别与联系
战略设计
- 案例背景介绍
- 建模和设计的整体流程
- 建立通用语言
- 子域和领域划分
- 核心域与精炼
- 上下文映射
- 分层架构
初涉战术设计
- 开发环境准备、基本约定和架构说明
- 战术设计分析和交易域依赖准备工作
- 实体和值对象
- 领域对象的构造
- 资源库与持久化
- 聚合
- 领域服务
- 应用层实现
深入战术设计
- 领域事件和事件风暴建模法
- 基于事件风暴建模法对运营域建模
- 防腐层的构建
- DDD在大数据ETL和分析场景的应用
架构升级:从单体到微服务
- 为什么要微服务,微服务的前提和基础
- 微服务的问题和DDD的答案
- 微服务主流框架简介
- 基于DDD思想进行服务拆分
- 基于服务网络技术对案例系统进行微服务改造
- 使用K8S进行服务编排,部署上云
DDD 实践中的问题和关键点
- 持续集成的重要性及如何搭建
- 如何避免漏掉重要细节
- DDD的局限性,不能解决什么问题
总结与展望
- DDD的核心思想与方法回顾
- 程序员的技术生涯
技术储备
- Java 语言基础
- Sprint boot 基本应用
# DDD 的核心思想和解决的痛点问题
- 什么是模型和建模?
- 软件系统的复杂性来自哪里?
- DDD 的关键思想以及如何应对多变的复杂性?
小结
- 模型是对领域的抽象,建模是针对特定问题建立领域的合理模型
- 复杂性来源于业务本身的复杂性和设计引入的额外复杂性
- 领域驱动设计通过分解模型和模型驱动设计控制复杂性
# 面向对象和敏捷与DDD的区别与联系
面向对象(OOAD)
- 对象设计与分析与DDD在同一层
- 工具的复用与DDD一致
- 区别是DDD更加详细,能够应对复杂系统的开发
敏捷
- 是一种流程与文化
- 敏捷轻文档,DDD战略设计需要统一语言进行详细描述
- 敏捷与DDD是互补的关系
# 敏捷的过去、现在与未来
领域驱动设计的诞生
- Eric Evans 1966.12.28
- 《领域驱动设计:软件核心复杂性应对之道》2003
领域驱动设计的发展历史
领域驱动设计的现状和未来
# 战略设计
# 智慧零售案例项目介绍
零售行业
- GDP 39.2 万亿,经济占比百分之40左右
- 线上9.7万亿(实物)(24.9%)
- 线下27.4万亿(70%)
智慧零售/新零售
- 供应链
- 用户体验
- 货
- 场所
- 人
- 云+大数据+AI+物联网
业务背景
面向自动售卖机的零售Saas

Smart Retail Machine(智能零售机器)
团队背景
A公司:SaaS公司,主要面向零售企业客户
SmartRM产品团队:以为资深产品经理,几位产品策划
SmartRM研发团队:一位架构师,10+开发,资深开发3至4位
客户背景
B集团:零售行业某头部商家
全国各地大量商超和便利店,由成熟的内部系统和供应链
基于自动售卖机的零售业务是新业务
案例优势
复杂度可覆盖DDD大部分知识点,并体现其价值
智慧零售市场庞大且场景接近日常生活
有数据分析需求,可结合大数据分析场景
小结
- 行业背景
- 业务、团队、客户背景
- 案例目标和优势
# 建模和设计的整体流程
软件系统从需求到最终技术方案包含的环节
- 挖掘用户故事
- 建立通用语言
- 战略设计
- 战术设计
- 建模涡流(Model Exploration Whirlpool)
- 战略设计 -》 战术设计 -》 战略设计
- 领域划分 -》 寻找BC -》领域划分
参与人员:
- 产品团队
- 领域专家
- 研发团队
各环节的目标和概要
用户故事:
- 问题空间的描绘
- 文字表述
- 讨论+图形表达(ER图,或者将问题拆分步骤将问题分布画图表示)
采用3C对用户故事描述
Card(卡片--Who What Why)、Conversation(谈话),Confirmation(验证)
通用语言:
- 在讨论模型和定义模型时,团队使用的同一种语言
- 领域知识需要在团队内部高效流转,模型需要描述
- 通用语言要体现在代码里
战略设计:
- DDD 中对问题空间和解决方案空间进行分解的过程
- 目的是分解模型以控制复杂性
- 是DDD与传统建模和设计方法的核心区别之一
步骤:
- 领域划分
- 寻找限界上下文(BC)
- 确定上下文映射

战术设计:
- 对各个BC的细节设计过程
- BC内部的模型结构与完整技术方案
(作者认为战术设计是包括编码的)

常用建模方法
- Domain Storytelling (领域故事陈述法)
- Event Storming (事件风暴法)
- 4C (四色建模法)
小结

# 从用户故事到通用语言
用户故事
- 代码写好后修改需求?
- 需求文档不细致,关键点没有?
- 不要拍脑袋定需求
- 基于用户故事讨论
通用语言
三个要素:
- 一种描述摩西那个且基于模型的语言
- 团队在进行所有交流时都使用它
- 代码中也要体现
包括:
- 类和操作的名称
- 施加与模型之上的规则和约束(如补充货物,超过了售货机上限)
- 应用于领域模型的模式(工厂、库,上下文)

讨论中的起初建立的通用语言与模型可能与领域有差距,但是通过讨论与纠正,最终的模型慢慢靠近显示世界的领域合理模型。如果只是使用自然语言,则每个人的见解不同,无法做到模型的统一。
小结
- 使用Domain Storytelling 方法分析用户故事
- 通用语言的定义、作用、与构成,以及如何建立
# 领域划分
- 什么是领域划分和子域
- 为什么要进行领域划分
- 基于用户故事分解的领域划分方法
什么是领域划分
- 领域划分是以分离关注点为原则对空问题空间的划分
- 子域是领域中某个方面的问题和解决它所涉及的一切
基于用户故事,先进性简单分域:

为什么要进行领域划分
- 传统需求开发,问题点和领域知识重叠

- 模型重叠

领域划分可以解决传统模式的问题
- 不同子领域聚焦不同问题

基于故事分解的领域划分
售货机扫码支付购物,用户故事图

故事再划分:支付二维码

分解什么时候停止:问题足够聚焦,聚焦到一个领域问题,甚至可以是一个原子操作。
用户故事分解树状图:

将所有节点穿起来,并归类,将每个类别起个名称:

交易域拆分结果:

分解运营域具体过程查看文档,最终可得到:

小结
- 领域划分是对问题空间的划分,划分的原则是分离关注点
- 基于领域划分进行分工协作而非基于需求
- 基于用户故事分解可以让领域划分清晰化(该过程并不是机械化,分解的而是需要思考与讨论的)
系统设计仍然有他的艺术性,同一个问题分解的的方式可以不一样,实际上分解本身就是从问题空间向方案空间进行的过程,分解方案就是解决方案的一部分,提供的方法只是一种辅助分析的方法,这种方法是有效的,但它不是机械的操作流程,分解的过程中,仍然需要大量的思考和团队的讨论,不同的分解方式会导致不同的方案和效率,好的分解,才能导入好的方案。
# 核心域和精炼
- 子域的类型
- 核心域的意义
- 什么是精炼及精炼的方法
子域的类型
- 核心域
- 通用子域
- 支撑子域
精炼
- 萃取(随着对领域分析的深入,逐渐发现最能影响产品成功的关键问题)
- 分离(对问题分解,将对核心领域影响不大的部分剥离出来)
本案例中,交易域的分解就是精炼的过程
小结
- 战略设计要明确核心域,团队尽量减少非核心域投入
- 从个人发展角度,程序员也要尽量投入核心域的工作
- 核心域的建立总是伴随着精炼,精炼有两总方法
SmartRM系统领域划分

# 限界上下文
- 什么是限界上下文
- 为什么需要限界上下文
- 如何划分限界上下文
- 限界上下文和微服务的关系
什么是限界上下文
Vaugh Vernon 《领域驱动设计》
限界上下文是一种语义上的上下文边界。意思是在这个边界里的软件模型组件都有它特定的含义并且做特定的事。一个限界上下文内的组件都是上下文特定的并且语义明确的。

为什么需要限界上下文
- 自然语言具有模糊性
- “你这是什么意思”, “没什么意思,就是一点小意思”
- 同一个事物面向不同的场景有不同模型
- 软件系统需要分解模型以控制复杂度
不分解的话,可能最后会变成很一个大泥球的模型,系统会难以维护

- 限界上下文是分工的单位(与子域分配并不冲突)
如何划分限界上下文
- Domain Storytelling (领域故事陈述法)
- Event Storming (事件风暴法)
- 基于子域概念提取
Domain storytelling 中边界特征(2018年前后,比较新)

- 单向联系
- 语义区别
- 活动的触发方式不一样
有时候,满足三个条件的时候也可以不用限界上下文,但有时候只有一个条件,却需要限界上下文,当然坏的方式都有一些类似的味道。不同的方案有不同的优势,具体取决于架构师和开发团队。
限界上下文是大一些好还是小一些好,是多一些好还是少一些好?系统划分是否有一个标准呢,系统的建模和设计并没有一个答案,边界的标志也并不是绝对的,在前期的限界上下文设计里,需要宁缺勿滥。比如过早划分限界上下文,有可能缺失全局优化的机会。如果确实属于不同的上下文,那么我们迟早会发现。

Event Storming 事件风暴法(如日中天,可以说是DDD中,最重要的建模方法)
后续补充
基于子域概念提取
前两种方法,划分限界上下文,需要深入业务中,分析清除具体业务才可以对上下文的划分。
该方法可以更快的划分限界上下文

通过分别从各子领域的用户故事中提取关键概念,审视他们之间的关系,以及他们与外部系统之间的关系,我们可以梳理出系统的限界上下文。

SmartRM 子域和限界上下文

小结
- 限界上下文是在解决方案空间对模型的分解单位
- 限界上下文的作用:控制复杂性,便于分工协作
- 限界上下文的三种划分方法
- 限界上下文和微服务的关系:后者是前者的一种实现方式
# 上下文映射(Context Mapping)
- 什么是上下文映射?为什么需要上下文映射?
- 上下文映射有哪些模式?
- 各个上下文模式的含义与应用
什么是上下文映射
- 上下文映射是指限界上下文之间的模型映射关系
- 描述团队之间的协作关系以及上下文之间的集成关系
- 决定上下文之间如何集成以及如何设置防腐层
上下文映射模式

开放主机服务
服务提供方为所有消费方提供一套公共的API
针对通用的功能和模型

顺从者
- 没有模型到模型的转换
- 一个上下文沿用另一个上下文的部分模型
大泥球
- 由混杂的模型构成糟糕系统,模型不稳定且难于维护
- 于大泥球合作的上下文要确保自身不被污染,设置防辅层
防腐层
- 把上游上下文的模型转换成自己上下文的模型
- 是下游上下文中访问外部模型的一个代理层
共享内核
- 两个上下文共享部分模型
- 包括但不限于代码、jar包、.so、数据库表等等
- 慎用,仅当团队紧密合作且共享部分稳定
合伙人
- 技术无关,是一种团队协作关系
- 两个团队之间可以随时互通有无,协同变更
客户/供应商
- 下游上下文可以向上游上下文提供需求
- 一般用于核心域与非核心域之间的协作

假设我们依赖业务中台,那么我们与业务中台,中台是上游,我们是下游,那我们是=是顺从者,还是客户/供应商的上下文关系呢?中台应该是低姿态的一方,中台的价值在于整合各个业务相对成熟通用的部分,并沉淀对业务有价值的通用组件,中台的价值一定要也只能体现在业务上,而业务呢也只能是下游的上下文。但是中台也有中台的难处,为什么这么说呢?当我们要顺从上下文的时候,自己的上下文就很容易变成大泥球,如果我们要给多个上下游当供应商会怎么样呢?其实也是一样的,所以中台也很容易变成大泥球,他的模型很难稳定下来,它的设计是非常需要智慧和技巧的,也需要具备一定的开放性,中台团队不给力,总是要让下游当顺从者,最后中台很可能变得形同虚设,下游的上下文在被逼无奈的情况下可能会选择分道扬镳。
“分道扬镳”
- 两个上下文无协作,各自独立
- 当两个上下文之间的集成成本过高

公开语言
- 标准化与协议化的模型
- 所有上下文都可以与公开语言中的模型进行转换
- 对接了公开语言的上下文之间可以实现组件化对接
例子:
- 蓝牙协议,tcp/ip
- Java 生态的 jdbc、jvm 标准等
- SQL
项目案例的上下文映射关系

小结
- 上下文,团队之间的关系,重叠模型的映射关系
- 上下文映射有九种模式
团队明确自己的定位,怎么样与其他团队协作
# 用分层架构隔离领域模型
- 为什么要隔离领域模型
- DDD传统四层架构和洋葱(六边形)架构
- 如何建立分层架构
模型驱动设计和分层架构
- 严格按照领域模型来编写代码
- 建模和实现中都有破坏该原则的因素
- 架构分层能够避免模型在实现过程中被省略或者污染
分层架构是一种古来的技术传统
传统架构如MVC缺点:围绕数据编程,变成贫血模型,业务被存储层绑架,业务与技术混杂在一起,领域模型也被技术方案绑架,最后如果需要替换存储,改变技术方案,可能业务代码也需要进行巨大的修改。可能有的同学会说,我们不是也做过分层吗?【client, controller,dao,entity,service】其实这些分层是不够的
传统方式的问题
- 领域模型易被省略掉,变成贫血模型
- 容易演变成基于数据的设计,一切从表结构开始
- 领域模型与技术实现混杂,易被技术实现绑架
DDD 传统四层架构

接口层:外部通信,如协议的解析封装,路由等待等
应用层:主要面向问题空间,指挥领域模型和基础设施来完成用户故事,工作包括像事务的控制,事件订阅,从资源库读写模型等等。
领域层:核心层,包含了我们领域中的领域模型,领域中的实体,资源库,领域事件,工厂等等元素
基础设施:通用的框架,工具,数据库表,存储访问等等
以交易上下文为例:
- application.service
- TradeService
- domain
- entity
- Order
- OderState
- SlotVendingMachine【货道售卖机】
- repository
- impl【资源库的具体实现】
- OderRepositoryImpl
- SlotVendingMachineRepositoryImpl
- OrderRepository
- SlotVendingMachineRepository
- impl【资源库的具体实现】
- service
- OrderService
- entity
- infrastructure
- dao
- dataobject
- remote
- interf
- controller
- vo
DDD 传统四层架构解决什么问题
- 分离关注点
- 让领域模型层变得更独立
- 单向依赖
DDD 传统四层架构的缺陷
- 领域层对基础设施层仍然有感知,领域模型和技术实现耦合
依赖倒置和洋葱(六边形)架构

核心思想:把领域模型放到了核心层,领域模型变得极其的存粹和独立,围绕他的就是一些适配器,适配器的作用就是完成领域模型和外部系统的数据交换或收发消息和读写数存储。
对交易领域进行改造
- adapter
- remote [远程服务调用的封装实现] [接口定义在领域层]
- VendingMachineServiceAdapter [对领域层的接口进行具体实现]
- repository.impl [将领域层资源库的实现放到适配器层]
- OderRepositoryImpl
- SlotVendingMachineRepositoryImpl
- api [由适配器层完成消息的收发和路由]
- vo
- controller
- eventhandler [领域事件监处理器]
- failedEventHandler [还是调用领域模型或者应用服务来处理事件]
- repository.impl [领域资源库的具体实现]
- OrderRepositoryImpl
- remote [远程服务调用的封装实现] [接口定义在领域层]
- application.service
- TradeServic [没有太大区别]
- domain
- entity
- remote [将基础设施层的接口移动到了领域层]
- VendingMachineService [具体的实现也放到了适配器层]
- repository [领域仓储只保留了适配器层的接口]
- OrderRepository
- SlotVendingMachineRepository
- service
- infrastructure
- dao
- dataobject
领域的资源库的实现放到了适配器层,领域的资源库只保存接口,因为本质上资源库的实现,完成的是领域模型和数据存储层之间的数据交换。
基础层的远程服务调用拆成了两部分,接口放到了领域层,实现也放到了适配器层,本质上调用其他上下文外部服务,其实就是对上下文映射的一种实现,这种服务调用其实就代表了,从我们上下文看其他上下文的模型是什么样子,所以本质它也是我们的领域模型和其他上下文领域模型的数据交换,我们需要在在这种adapter中完成领域模型的转换,包括防腐层,也可以实现在里面。
洋葱(六边形)架构优势
- 保持领域层的存粹性,不受其他因素干扰
- 便于践行模型驱动设计,代码跟随模型
- 便于把团队精力集中到领域模型
小结
- 分层架构有利于实现模型驱动设计
- 从四层架构到洋葱(六边形)架构 ---- 案例
- 如何建立分层架构 -- 建立 smartrm 的分层架构(洋葱架构)
# 初涉战术设计
- 什么是实体和值对象
- 为什么要区分实体和值对象
- 如何区分实体和值对象
# 什么是实体和值对象
- 实体
- 主要由标识定义的对象被称作 ENTITY
- 值对象
- 用于描述领域的某个方面,而本身没有概念标识的对象称为值对象
需要以ID来跟踪状态变化的对象为实体,否则为值对象
对象的相等性
- 标识符相等性 , 如:身份证号 中国公民
- 引用(指针)相等性(领域中价值不是很大,可以先不考虑)
- 属性相等性,如:品牌,版本,容量,制式 指向一个手机型号
实体:
- ID 相等性
- 要跟踪状态变化
值对象
- 属性相等性
- 可互换
- 不变性
# 为什么要区分实体和值对象
- 值对象往往更轻量级
- 值对象不用跟踪状态变化
- 实体和值对象在领域中扮演的角色不一样
尽可能使用值对象而不是实体
实体可以作为聚合的聚合根,而值对象是不可以的
为了更好的建立领域模型,并且用更低的成本去实现领域模型
分辨实体和值对象
- 根据上述技术特征
- 更直观的领域模型特点
- 是否只读
- 生命周期是否跨越活动
# 领域对象的构造
# 聚合
一个上下文中存在多个领域对象,每个领域对象需要强一致性,使用聚合实现是非常合适的。
也需要灵活的使用聚合,在一些特殊场景下
# 领域服务
领域服务中只写业务,应用服务则负责指挥领域对象配合完成工作。
- 业务逻辑是否可以放在实体或值对象
- 仅在必要的时候引入领域服务
- 相关代码是属于领域服务还是应用层
- 领域服务于应用层服务的区别
# 应用层
- 应用层的定义和职责
- 应用层的实现方法
什么是应用层
“定义软件要完成的任务,并且指挥表达领域概念的对象来解决问题。这个一层所负责的工作对业务来说意义重大,也是与其他系统的应用层进行交互的必要渠道应用层要尽量简单,不包含业务规则或则知识,而只为下一层中的领域对象协调任务,分配工作,使他们相互协作” --- Eric Evans 《领域驱动设计》
应用层的职责
- 事务控制
- 身份认证和访问权限
- 定时任务调度
- 事件订阅
- 事件监听(适配层)
- 事件处理(应用层)
应用服务和领域服务的区别
- 应用服务(不包含业务逻辑)
- 事务控制
- 访问权限
- 任务调度
- 调用领域层
- 领域服务
- 业务逻辑
小结
- 应用层是调用领域模型完成用户需求的地方
- 应用层的实现
- 事务
- 鉴权
- 任务调度
# 本章总结
- 适配层的实现
- 与阿里云IoT对接
- 运行演示
# 深入战术设计
- 领域事件和事件风暴建模法
- 防腐层的构建
- DDD 和 大数据
# 领域事件为什么重要
- 领域事件能够驱动建模
- 领域事件和很多重要思想相关
- CQRS
- Event Soucing
- 领域事件和大数据处理和分析相关
# 建模工具
- 便利贴
- Miro
- 在线,可联机协作
- 免费版体验差
- draw.io
# 领域事件
- 什么是领域事件
- 领域事件的基本属性
- 领域事件的发布和订阅
- 领域事件的存储
- 事件处理的要求
- 领域事件和大数据分析
什么是领域事件
- 领域中发生的任何领域专家会感兴趣的事情
- 领域事件一般由聚合产生
- 领域事件不是技术概念
事件命名和基本属性
- 命名方法
- 事件ID
- 产生时间
这些属性可以作为领域事件的原始对象的属性方便其他事件继承
发布和订阅方式
- 外部系统
- API 定向通知
- API 定时拉取
- 消息队列【需要注意加密】
- 内部系统
- 观察者模式
- 数据库流水
- 消息队列
事件存储
- 直接使用消息中间件的存储
- 冗余机制
- 做好备份
- 基于数据库
- mongodb
- postgresql
- mysql
- 分布式
- 按时间分区
事件处理的要求
- 顺序性
- 聚合ID
- 存储分片
- 消费分组
- 幂等性
- 用幂等性代替分布式事务
- 状态判断或去重
# 从单体到微服务
- 为什么要重构,微服务的优点
- 微服务的问题和DDD的答案
- 微服务的基础设施
- 基于DDD对案例项目进行服务划分
- 基于微服务架构对案例项目进行改造
- 基于k8s进行容器编排和服务部署
# 为什么要微服务和实现微服务的前提基础
当前架构

当前架构的问题:
- 系统过于庞大,模块过多,系统发布的代价大,多个上下文小伙都必须一同上线
- 问题分析,问题定位职责不清晰
微服务架构:

# 微服务的好处
- 技术异构性
- 容错性
- 灵活拓展
- 简化部署
- 与组织结构匹配
- 可组合性
- 方便替代和升级
# 微服务的基础
- 服务注册和发现
- 服务监控
- 熔断降级
- 流量控制
- 安全性
- 配置管理
# 微服务的问题
- 服务划分
DDD 中 可以使用聚合来划分,该种划分方式,粒度较小,性能开销较大
目前划分一般使用限界上下文进行划分
# 微服务主流方案介绍
方案一:微服务SDK(框架)

常见微服务框架:
- Spring Boot with Spring Cloud
- GoMirco 【go语言下的】
- Molecular
- Quarkus
- Lagom
- Axon
方案二:服务网格

无侵入性,相当于老板的司机
两总方案对比
- 侵入和非侵入性
- 是否支持技术异构性
# 基于DDD思想进行服务拆分和重构
服务划分 -》 基础设施层重构 【事件总线改造,数据库拆分】-》 服务重构【共享内核,服务调用】
# 使用k8s进行容器编排和服务部署
为什么是k8s以及为什么要学
- Kubernetes 是容器集群管理系统,是一个开源平台
- 硬件资源管理调度,应用部署的事实标准
- 业务架构师需要懂运维
K8s Service 的类型
- ClusterIp
- NodePort
- LoadBalancer
- ExternalName
# 实践中的问题和关键点
# CI/CD的重要性及如何搭建
- CI (持续集成)
- 通过自动化流程持续把各个开发者的工作集成到一起,避免过大的集成成本。
- CD (持续交付)
- 通过自动化测试和不是流程使软件系统随时处于可发布状态
# CI/CD最核心的是什么?
- 单元测试 【代码覆盖率】
- 集成测试
# DDD的厂家难问题,争论以及局限性
资源库与领域服务的区别?
资源库与领域服务似乎起到的是同一个作用,聚集下方资源提供给上层调用,这两个有什么实际区别吗?
资源库适用于对象存储,领域服务是无处反方的业务逻辑
按照DDD 写代码是否会导致过度设计?
按照DDD写代码似乎对编码的要求与系统理解更复杂了,一个业务是由多个领域对象同时分担处理,要是测试项目紧急加新人进来做新业务,完全无法了解这些领域对象具体提供了哪些服务,由一种系统被过度设计的感觉
DDD 并不适用于解决代码的所有问题,而是用于解决业务复杂性。DDD 是防止过度设计的,因为一切的代码跟着业务走。
DDD 是否战略设计的意义要大于战术设计
模型驱动设计和面向数据库表的设计有什么区别?数据驱动的去点是什么?为什么要使用DDD?即使不用DDD,而是面向数据库表开发,也能搭建一套稳定的代码结构。
作者理解:DDD就是一套方法论,一个作用是用于拉齐项目中各个角色对于需求的认知,高效率的让项目中涉及的“知识”在团队内流转,这个是扎略涉及的作用;另一个作用就是将战略实际划分领域模型,通过使用展示涉及的各种“武器”,比如实体,值对象,仓储层,防腐层等等,将领域模型落地成高度抽象且领域层稳定的代码。
但是我有个问题是在DDD中是不是战略设计意义要大于战术设计,因为我之前做代码设计的时候,那时候不知道防腐层等概念,但是还是会做类似的抽象,经过良好抽象的代码即使是那种“事务脚本”的形式也是稳定的,所以我感觉如果仅仅是代码层面的问题只要是进行了良好抽象其实无论是面向数据还是面向领域是没有区别的?
问这个问题的原因是我在之前做项目的时候提出要使用DDD,然后我的老板问为什么要用,我表达了战术设计能够指导代码抽象等观点,然后我的老板就说这是代码设计层面的问题,我感觉我没有办法反驳。
DDD和面向数据库表开发有什么区别,因为我理解只要做好代码设计,即使不用DDD,而是面向数据库表开发,也能搭建一套稳定的代码结构。
---- 使用DDD理论下,对开发的过程可以使用理论对当前的代码以及架构进行评估,而不是面向数据库表开发,后期遇到变动而无法解决才暴露问题。
# 总结与展望
# DDD的核心思想与方法回顾

Domain storytelling 中边界特征 --- 用于区分限界上下文方法一
- 单向联系
- 语义区别
- 活动的触发方式不一样
基于领域划分的基础上进行限界上下文划分

通过分别从各个子域的用户故事中提取关键概念,审视他们之间的关系,以及他们与外部系统之间的关系,我们可以梳理出系统中的限界上下文。如下图所示:

更简便的划分方法,也需要更多的检验,可以在战术设计阶段确定聚合后,回来检验限界上下文,因为聚合是限界上下文最小的粒度
上下文映射模式
九种上下文的模式
← DDD导读 DDD事件风暴工作坊 →