您现在的位置是:首页 >技术杂谈 >设计模式:DDD领域驱动设计网站首页技术杂谈

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

Lvan的前端笔记 2024-06-12 12:01:02
简介设计模式: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;//区
 }

四色建模法

四色

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设计里不需要加上限界上下文。

落地

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

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。