从这一刻开始,请大家忘记自己是一名技术人员,用业务的角度来思考问题。

1、什么是DDD

  DDD(Domain-driven design,领域驱动设计),是一个很好的应用于微服务架构的方法论

  DDD要求项目全生命周期中,所有岗位人员都基于业务的角度去思考问题,而不是基于技术角度。

  “从理论到实践,再从实践到理论”——杨中科

2、领域(Domain)

  领域是指一个组织做的全部事情,可分为不同的子领域,子领域可用归为以下三类:

  核心域:解决项目的核心问题,和组织业务密切相关。

  支撑域:解决项目的非核心问题,具有组织特性,但不具有通用性。

  通用域:解决通用问题,没有组织特性。

  领域的不同分类决定了公司的研发重点:

  比如:某软件公司,将领域分为

    

3、领域模型(Domain Model)

  用业务的角度,对领域内的元素进行建模,抽象出来的模型图。

  比如,银行中有:柜员、客户、ATM、保安、取号机...

  识别出这些模型,再用模型描述和构建系统

4、事务脚本

  也可称为:伪代码,以易读性为准,用类似代码的语法表达业务需求,如

string WithdrawMoney(string acc,string pwd,double nums) //取钱
{
if (!checkUser(acc, pwd))
{
return "账户错误";
}
double remainingSum = GetRemainingSum(acc); //获取余额
if(remainingSum< nums)
{
return "余额不足";
}
UpdateRemainingSum(remainingSum - nums); //更新余额
return "取款成功";
}

5、通用语音  &   界限上下文

  5.1、通用语音:一个拥有确切含义,没有二义性的语音

    产生二义性的例子:定义一个对象为"用户",这个用户是指柜员、储户、还是客户经理,没有确切定义,这就是二义性

  5.2、界限上下文:通用语音离不开特定的语义环境,只有确定了边界,才能没有歧义的描述一个业务,比如:

    1)后台管理系统用户:是指系统管理员、系统流程人员

    2)官方网站用户:是指储户、信用卡用户

6、实体(Entity) &  值对象(Value Object)

  6.1 实体:可用理解为实体对象,是富有业务行为且具有唯一标识符的对象。在不同的设计阶段实体是可以改变的,但是根据唯一标识符始终能定位到这个唯一对象,如员工(Code:对于员工类)

  6.2 值对象:依附于实体存在,如员工居住地址。(Code:对应地址类)

7、聚合(Aggregate)   &    聚合根

  目的:实现高内聚,低耦合

  7.1 聚合:把关系紧密的实体,放到同一个聚合中,如,订单聚合包含:订单、订单明细

  7.2 聚合根:每个聚合,都有一个聚合根负责和外部对象进行沟通,如:通过订单访问订单明细

  聚合根和聚合内其他实体,体现的是整体和部分的关系,如:订单包含订单明细

  聚合的划分没有标准答案,根据业务进行划分。(Code:完善的划分有利于微服务的构建)

  聚合内的实体:只有对象创建、初始化、状态管理等个体相关代码,没有业务逻辑代码

  订单聚合例子:

  订单聚合:订单(根实体)、订单明细(普通实体)

  创建订单时,控制订单创建、判断订单数量,属于领域服务

   保存订单,属于应用服务

8、领域服务   &   应用服务

  8.1 领域服务:针对聚合内业务逻辑,不会和数据库发生直接交互,在简单的业务中领域服务不是必需的(避免过度设计)

  8.2 应用服务:针对跨聚合协作、聚合与外部系统协作逻辑(协调多个领域服务、外部系统来完成一个用例)

9、DDD典型用例处理流程

  第一步,准备业务操作所需要的数据。

  第二步,执行由一个或者多个领域模型做出的业务操作,这些操作会修改实体店状态,或者生成一些操作结果。

  第三步,把对实体店改变或者操作结果应用于外部系统。

10、仓储(Repository)  &   工作单元(Unit Of Work)

  仓储:读取数据/保存对实体的修改

  工作单元:聚合内的数据操作紧密相关,若干操作组成一个工作单元;

为保证事务的强一致性,这些操作要么全部成功,要么全部失败(事务)

11、领域事件   &   集成是事件

  领域事件:在同一个微服务内的聚合之间的业务传递,使用进程内的通信机制完成。

  集成是事件:跨微服务的业务传递,使用事件总线(EventBus)实现

12、贫血模型  &  充血模型

  贫血模型:只有属性和成员变量(属性带有get;set;本身并不保存值,值存在生成的隐式私有成员变量中)

  充血模型:属性、成员变量、方法

13、EFCore框架实现充血模型的五个要求

  1)属性是只读的,或者只能被类内部的代码修改

    实现:将属性的set定义为private或者init,然后通过构造方法为属性赋值

  2)定义有参构造方法,提供给类实例化

    因为EFCore会通过反射直接访问私有属性,实现方式可为:

    方式1:构造方法参数名(首字母小写)必须和属性名一致

    方式2:保留无参构造函数,定义为private,这是给EFCore从数据库加载数据用的

  3)没有定义属性的成员变量也需要映射为数据列,如passWordHash

    没有{get;set;}的是成员变量,也叫做字段,正常为private

    有{get;set;}的为属性,正常为public,(注意很多时候我们不会定义成员变量,系统会自动生成一个)

    实现:builder.Property("成员变量名")

  4)有的属性仅从数据库读,而不写

    EFCode中提供了支持字段"backing field",来支持这种写法

    实现:在配置实体类的代码中,使用builder.Property(e=>e.属性名).HasField("成员变量名")来配置属性为只读

  5)有的属性不需要映射到数据列,仅在运行时被使用

    实现:使用Ignore()来配置忽略

  

  

  

  

  

何为DDD的更多相关文章

  1. 一文读懂DDD

    何为DDD DDD不是架构设计方法,不能把每个设计细节具象化,DDD是一套体系,决定了其开放性,体系中可以用任何一种方法来解决这些问题,但是如果一些关键问题没有具体方案落地,可能让团队无所适从. 有的 ...

  2. DDD不是架构设计方法

    DDD不是架构设计方法 一文读懂DDD 2019-05-28 19:18 by 春哥大魔王, 413 阅读, 3 评论, 收藏, 编辑 何为DDD DDD不是架构设计方法,不能把每个设计细节具象化,D ...

  3. DDD实战与进阶 - 值对象

    目录 DDD实战与进阶 - 值对象 概述 何为值对象 怎么运用值对象 来看一个例子 值对象的持久化 总结 DDD实战与进阶 - 值对象 概述 作为领域驱动设计战术模式中最为核心的一个部分-值对象.一直 ...

  4. 如何运用DDD - 实体

    目录 如何运用DDD - 实体 概述 何为实体 似曾相识 你确定它真的需要ID吗 运用实体 结合值对象 为实体赋予它的行为 尝试转移一部分行为给值对象 愿景是美好的 现实是残酷的 总结 如何运用DDD ...

  5. 领域驱动模型DDD(二)——领域事件的订阅/发布实践

    前言 凭良心来说,<微服务架构设计模式>此书什么都好,就是选用的业务过于庞大而导致代码连贯性太差,我作为读者来说对于其中采用的自研框架看起来味同嚼蜡,需要花费的学习成本实在是过于庞大,不仅 ...

  6. 如何一步一步用DDD设计一个电商网站(九)—— 小心陷入值对象持久化的坑

    阅读目录 前言 场景1的思考 场景2的思考 避坑方式 实践 结语 一.前言 在上一篇中(如何一步一步用DDD设计一个电商网站(八)—— 会员价的集成),有一行注释的代码: public interfa ...

  7. 如何一步一步用DDD设计一个电商网站(八)—— 会员价的集成

    阅读目录 前言 建模 实现 结语 一.前言 前面几篇已经实现了一个基本的购买+售价计算的过程,这次再让售价丰满一些,增加一个会员价的概念.会员价在现在的主流电商中,是一个不大常见的模式,其带来的问题是 ...

  8. 如何一步一步用DDD设计一个电商网站(十)—— 一个完整的购物车

     阅读目录 前言 回顾 梳理 实现 结语 一.前言 之前的文章中已经涉及到了购买商品加入购物车,购物车内购物项的金额计算等功能.本篇准备把剩下的购物车的基本概念一次处理完. 二.回顾 在动手之前我对之 ...

  9. 如何一步一步用DDD设计一个电商网站(一)—— 先理解核心概念

    一.前言     DDD(领域驱动设计)的一些介绍网上资料很多,这里就不继续描述了.自己使用领域驱动设计摸滚打爬也有2年多的时间,出于对知识的总结和分享,也是对自我理解的一个公开检验,介于博客园这个平 ...

  10. 如何一步一步用DDD设计一个电商网站(七)—— 实现售价上下文

    阅读目录 前言 明确业务细节 建模 实现 结语 一.前言 上一篇我们已经确立的购买上下文和销售上下文的交互方式,传送门在此:http://www.cnblogs.com/Zachary-Fan/p/D ...

随机推荐

  1. 一文搞懂 Promise 新 Api allSettled 的用法和 all 区别,以及如何在不支持新特性的环境下实现一个 Polyfill

    开始 一文搞懂 Promise 新 Api allSettled 的用法和 all 区别,以及如何在不支持新特性的环境下实现一个 Polyfill allSettled 的用法 const runAl ...

  2. Windows亚克力特效代码实现(Dev c++可以编译通过)

    #include <windows.h> #include <dwmapi.h> // 定义一个枚举类型,表示不同的窗口组合状态 enum AccentState { ACCE ...

  3. 深入理解 python 虚拟机:描述器的王炸应用-property、staticmethod 和 classmehtod

    深入理解 python 虚拟机:描述器的王炸应用-property.staticmethod 和 classmehtod 在本篇文章当中主要给大家介绍描述器在 python 语言当中有哪些应用,主要介 ...

  4. 分享一个提高运维效率的 Python 脚本

    哈喽大家好我是咸鱼,今天给大家分享一个能够提升运维效率的 python 脚本 咸鱼平常在工作当中通常会接触到下面类似的场景: 容灾切换的时候批量对机器上的配置文件内容进行修改替换 对机器批量替换某个文 ...

  5. 2022-12-15:寻找用户推荐人。写一个查询语句,返回一个客户列表,列表中客户的推荐人的编号都 不是 2。 对于示例数据,结果为: +------+ | name | +------+ | Wil

    2022-12-15:寻找用户推荐人.写一个查询语句,返回一个客户列表,列表中客户的推荐人的编号都 不是 2. 对于示例数据,结果为: ±-----+ | name | ±-----+ | Will ...

  6. 2020-08-31:描述HTTP的版本之间的区别,主要是1.0/1.1/2.0三个版本的区别。

    福哥答案2020-08-31: HTTP1.0与HTTP1.1的主要区别 1.长连接HTTP1.0:需要使用keep-alive参数来告知服务器端要建立一个长连接.HTTP1.1:默认支持长连接.2. ...

  7. 2022-07-29:一共有n个人,从左到右排列,依次编号0~n-1, h[i]是第i个人的身高, v[i]是第i个人的分数, 要求从左到右选出一个子序列,在这个子序列中的人,从左到右身高是不下降的。

    2022-07-29:一共有n个人,从左到右排列,依次编号0~n-1, h[i]是第i个人的身高, v[i]是第i个人的分数, 要求从左到右选出一个子序列,在这个子序列中的人,从左到右身高是不下降的. ...

  8. 2021-02-28:给定一个整型数组arr,和一个整数num。某个arr中的子数组sub,如果想达标,必须满足:sub中最大值 – sub中最小值 <= num,返回arr中达标子数组的数量。

    2021-02-28:给定一个整型数组arr,和一个整数num.某个arr中的子数组sub,如果想达标,必须满足:sub中最大值 – sub中最小值 <= num,返回arr中达标子数组的数量. ...

  9. 2021-12-21:任务调度器。 给你一个用字符数组 tasks 表示的 CPU 需要执行的任务列表。其中每个字母表示一种不同种类的任务。任务可以以任意顺序执行,并且每个任务都可以在 1 个单位时间

    2021-12-21:任务调度器. 给你一个用字符数组 tasks 表示的 CPU 需要执行的任务列表.其中每个字母表示一种不同种类的任务.任务可以以任意顺序执行,并且每个任务都可以在 1 个单位时间 ...

  10. 解读与用户一起“跳动”的开源实时监控工具 HertzBeat

    摘要:开源项目遇上华为云,会擦出怎样的火花? 在本期<开源实时监控工具HertzBeat如何与用户一起"跳动?>的主题直播中,HertzBeat & TanCloud 创 ...