# 领域驱动设计是什么(what),为了解决什么(why)?怎么使用(how)?
领域驱动设计(Domain Driven Design), 是软件核心复杂性应对之道(要解决软件核心复杂性的问题)。
- 一种软件建设思潮,技术主动理解业务,业务如何运行,软件就如何构建。让不怎么使用技术语言的领域专家一起参与软件建设。
- 一种架构思想,将架构优化分散到每次需求迭代中,让复杂系统保持年轻。项目越复杂使用DDD的收益越大。
软件核心复杂性如果理解?怎么定义复杂性?
DDD的作者在提出这个概念的时候做的是电路,嵌入式的开发.
# DDD设计思想及核心四层架构模型
四层架构只是一个工具,更重要的是思想.
# 以领域划分为基础
核心域\支撑域\通用域, 优先完成核心域的开发,通用域可以外包或采购.如果用户关系系统.
# 以通用语言为核心
让项目中的人都能理解的语言结构,没有特定的格式,主要是让团队内的人达成一致.
# 以四层架构为工具

- 用户接口层: 用户界面\其他接口
- 领域层: 最核心的功能模块
- 应用层: 组成领域相关的能力变成业务场景,应用层不需要依赖外部的功能组件就能完成自己的业务能力.
- 基础层(基础设施层): 主要是对领域层的支撑,如果做数据的持久化,并不是必须的.
(应用层)转账的业务能力是需要依赖领域层来完成,需要一个账号进行扣减余额,一个账号需要进行增加余额.
# 有助于解决系统老化问题
- 解决开发越来越难的问题: 代码越来越多,没人敢去修改.
- 解决测试越来越难的问题: 单元测试麻烦,无法回归测试.
- 解决技术演进难的问题: 老系统太大无法重构,不能模块化修改.
微服务不也能解决这些问题?为什么需要DDD?
# 案例提供一个服务开发平台

# MVC 实现方式特点:
- 技术层次清晰,各层技术职责清晰,分工明确.
- 逻辑层次模糊,mvc各层之间的关联关系没有明确限定.
- 总结: 初期实现短平快,后期要做架构调整非常困难.

__软件核心的复杂性__并不是来源于庞大的软件体量或者复杂的业务流程,而是来自于项目长期迭代过程中不断冒出的超出当初设计之外的不确定性。
# 如何应用软件核心复杂性
- 技术人员主动理解业务。软件没有加载,是业务说了算,不是架构师说了算。
- 刚刚好解决问题。处理眼前的需求,避免过度设计,好用的自行车比看不懂的宇宙飞船更有价值。
# 服务开发平台解耦改造
DDD 概念 
充血模型: 将实体的属性及引起实体状态变化的方法都写到实体当中。
- 使用充血模型的实体对象,描述核心业务能力.
- 使用仓库与工厂,封装实体持久化操作
仓库封装DAO, 工厂转换领域对象
- 构建防腐层,隔离外部服务.
- 防腐层隔离第三方组件.
- 使用领域服务封装跨实体业务,保持实体纯粹性.
领域服务本身是没有业务能力的,都是调用实体的功能组成业务功能.
DDD 的好处
- 需求更容易梳理;
- 更容易单元测试;
- 更容易开发;
- 更容易更新技术;
# 服务开放平台构建领域地图
领域地图划分是非常重要的。业务专家、领域专家等一起划分领域地图。
代码仓库包设计

限界上下文

一个领域调用另一个领域只能调用对方暴露出来的业务能力. 这样领域与领域形成边界,称为限界上下文.
- 限界上下文主要是隔离领域之间产生的变化
- 限界上下文是领域模型的知识语境
- 限界上下文是业务能力的纵向切分
目前限界上下文的落地没有明确要求,可以在领域内添加一个adapter 对外提供能力来实现.
# 单体架构优先还是微服务架构优先?
MonolithFirst, 单体架构优先,不关什么系统都应该先使用单体应用开始,直到项目体积过大时才进行拆分.
因为项目前期对项目的业务理解不是很深刻,对应领域的落地及落地的效率也不是很清楚. 等各个模块的业务熟悉后在慢慢调整为微服务结构.
单体架构优先原则 
清晰架构 
菱形架构分层 
同类型对比单体应用调用\微服务调用\
- 单体架构调用

- 微服务架构调用

- MQ架构调用

构建领域仓库,实现领域服务

战术篇(当前是)\战略篇
- 战略工具: 统一语言\领域拆分
- 战术工具: 应用落地方法\基础设施统一
领域事件风暴怎么组织?
事件关注的是结果,不是过程.
问题空间子领域划分: 按业务职能划分\按业务产品划分\按业务环节\按业务概念划分
软件的复杂性是什么? 复杂难解: 难以理解, 复杂规模和复杂结构 复杂难测: 难以预测,业务需求不停的在变化要求在设计的时候要能够适应变化.
邮件服务 应用服务管理服务 BRAC 管理服务