设计模式:DDD领域驱动设计

文章介绍了领域驱动设计(DDD)的核心理念,强调业务导向和技术选择的关系。文中提到了实体、值对象、聚合根等DDD概念,并通过订单示例解释了它们在系统中的应用。此外,还探讨了事件风暴建模法和四色建模法两种建模方法,帮助理解和构建领域模型。

领域

Domain-driven design
DDD 强调是说得先把 “领域” 中涉及到的数据、流程、规则等都弄明白了,然后以面向对象的观点为其建立一个模型(即领域模型),而这个模型,决定了你将用什么技术、什么架构、什么平台来实现这个系统。所以技术在这个过程中是 “被动的”,是被 “选来” 实现 “领域模型” 的。对于项目的成败,技术不是决定性因素,领域模型是否符合事物的本质才是关键。

可以看出,领域驱动设计的出发点是业务导向,技术服务于业务。
在这里插入图片描述

实体

比如商品是商品上下文的一个实体,通过唯一的商品 ID 来标识,不管这个商品的数据如何变化,商品的 ID 一直保持不变,它始终是同一个商品。

值对象

实体是看得到、摸得着的实实在在的业务对象,实体具有业务属性、业务行为和业务逻辑。而值对象只是若干个属性的集合,只有数据初始化操作和有限的不涉及修改数据的行为,基本不包含业务逻辑。值对象的属性集虽然在物理上独立出来了,但在逻辑上它仍然是实体属性的一部分,用于描述实体的特征。在值对象中也有部分共享的标准类型的值对象,它们有自己的限界上下文,有自己的持久化对象,可以建立共享的数据类微服务,比如数据字典。

比如将用户的住址就设计为了值对象——住址是用户的属性的一部分,它包含国家、省份、城市、区、街道等。

聚合/聚合根

如果把聚合比作组织,那聚合根就是这个组织的负责人。
聚合根也称为根实体,它不仅是实体,还是聚合的管理者。
一组相关对象的集合,作为一个整体被外界访问。聚合根的 ID 全局唯一

关系

通过聚合根来引用实体,挂载值对象,对外屏蔽内部的实体逻辑

//聚合根
 class Order {
     public String id;//订单ID,全局唯一
     public Address customerAddress;//配送地址
     public List<Item> items;//商品信息
     public Pay pay;//支付信息
     public LogisticsDetail logisticsDetail;//物流信息
     public Pingjia pingjia;//评价信息
 }

 //实体
 class Item {
     public Long id; //商品ID,实体主键,Order内唯一
     public String name;//商品名
     public float price;//价格
     public int count;//数量
 }

   //实体
 class Pay {
     public Long id; //支付ID,实体主键,Pay内唯一
     public String source;//支付方式
     public int currency;//币种
     public float total;//价格
 }

  //实体
 class LogisticsDetail {
     public Long id; //物流ID,实体主键,LogisticsDetail内唯一
     public int cpCode;//物流公司
     public String mailNo;//物流单
     public float status;//当前状态
 }

 //实体
 class Pingjia {
     public Long id; //评价ID,实体主键,Pingjia内唯一
     public String desc;//描述
     public byte[] image;//图片
 }

 //值对象
 class Address{
     public String province;//省
     public String city;//市
     public String county;//区
 }

接下来介绍两种常见的领域建模方法。

  • 事件风暴建模法
  • 四色建模法

事件风暴建模法

事件风暴通过事件、命令与策略之间的响应关系来组织逻辑。它定义了一套彩色贴纸的”语法”: 不同颜色的贴纸都有定义。浅黄色代表角色(Actor)、蓝色表示命令(Command)、粉色代表业务规则(Policy)、紫色代表系统(System)、橙色代表事件(Event), 绿色表示阅读模型(Read Model)、红色代表热点问题(HotSpot)。

每种语法的具体含义如下:

  • 行动者(Actors)是系统的使用者。这里使用者是一个相对模糊的概念,可能是现实中的人也可能是别的系统;
  • 命令(Command)是由行动者发起的行为。它代表了某种决定,通常是事件的起因,也称作行动者触发命令(AIC,Actor Initiated Command);
  • 事件(Event)就是我们前文讨论过的事件;
  • 系统(System)指代的是不需要了解细节的三方系统。因为不需要了解细节,所以我们可以将它们看作一个整体;
  • 阅读模型(Read Model)用以支撑决策的信息。通常与界面布局有关;
  • 策略(Policy)是对于事件的响应,通过策略可以触发新的命令,由策略触发的命令,被称作系统触发命令(SIC,System Initiated Command)。
  • 热点问题(HotSpot)是业务痛点,瓶颈,模糊点。如果有争论,可以将双方观点用热点问题的形式记录。

在这里插入图片描述

四色建模法

四色

1、时标原型(Moment-Interval Archetype,简称MI)
表示事物在某个时刻或某一段时间内发生的,如销售订单、客户账单、收款记录等,使用浅红色表示。

2、PPT原型(Part-Place-Thing Archetype,人/事/物原型,简称PPT)
表示参与扮演不同角色的人或事物,如商品、账户、店铺等,使用浅绿色表示。

3、角色原型(Role Archetype,简称ROLE)
抽象了一种参与方式,由人或组织机构、地点或物品来承担,如客户、商家、仓储团队、财务组织等,使用浅黄色表示。

4、描述原型(Description Archetype,简称DESC)
属于资料类型的资源、目录式的种类性质对象,或者可以被其他原型反复使用的,如商品类目、支付方式、方法值对象等,使用浅蓝色表示。

步骤

接下来,咱们使用四色建模法来分析领域模型,总共分为四大步:

建立时标原型:寻找需要追溯的事件,根据追溯事件寻找足迹。
建立PPT原型:丰富模型,寻找时标原型周围的人/事/物,使它可以更好地描述业务概念。
建立角色原型:进一步从中抽象出可以参与到不同流程中去的角色。
建立描述原型:把一些信息用描述对象补足。

示例

电商DDD的四色图案例
在这里插入图片描述
财务领域模型和支付中心模型的一部分
在这里插入图片描述
在这里插入图片描述

细节

  • 粉红色指的是时标原型,是核心业务产生的数据,基本上对应表设计。
  • 模型属性不需要体现表的审计字段,比如通用的ID、创建者、修改时间、软删除标识等,模型行为也只需要设计核心行为即可,那种约定俗成的- CRUD方法就不需要写出来了,设计要懂得取舍。
  • BC内模型除了依赖、聚合等等连线,可使用箭头连接模型之间的核心交互,跨BC之间的模型使用虚线箭头连接,这里我是结合了DCI建模法(D表示数据,C表示上下文、场景,I表示模型间的交互)。
  • 对于表示业务唯一的属性,我使用了加粗展示,再也不用跟别人费劲去解析这些模型是用什么维度去建的了
  • 对于还没上线的属性变动(新增/修改),使用红色标记,因为领域模型图是指导我们业务开发的。
  • 限界上下文的划分是一种非常主观的边界划分,为了后续代码能够灵活调整,在Controller的URL设计里不需要加上限界上下文。

落地

最好由架构师给出设计方案,并给出骨干实现,开发人员有了可类比的代码,就能够比较准确的去做功能开发。

资料

https://mp.weixin.qq.com/s/HMLpjcE0UENUTfMK0Z9n8A

评论 7
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Lvan的前端笔记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值