关于领域模型DDD的一些思考

文章探讨了DDD(领域驱动设计)的核心理念,强调领域模型对复杂需求的应对,以及随着需求迭代其优势的显现。作者指出,好的DDD能促进系统的优雅扩展和降低代码腐化。通过杯子与装水容器的比喻,阐述了如何从具体产品抽象出通用功能,以及在建模过程中定义的重要性。文章还分享了作者在实际项目中如何进行领域建模的经验,特别是如何从定义出发构建领域模型,并提到防腐层在保护领域模型稳定性中的作用。
摘要由CSDN通过智能技术生成

究竟什么是DDD?

DDD(Domain-driven design)领域驱动设计是一种通过将实现连接到持续进化的模型来满足复杂需求的软件开发方法。领域模型是对业务模型的抽象,DDD是把业务模型翻译成系统架构设计的一种方式。

为什么要做DDD?

网上对于ddd好处的文章一抓一大把,笔者觉得好的ddd可能在项目初期并不一定能发挥多大作用,反而会让业务,开发觉得浪费时间,coding更多。

但随着时间推移,需求不断迭代,好的ddd的优势会逐渐凸显出来

●更易/优雅扩展的优势,针对不同业务场景的快速拔插

●降低代码腐化的速度

简单来说,领域模型是我们看待事物或者这个世界的方式,就像网络小说中的高手一样,当主角到达一定高度后,看世界都像是用一根根规则的线组成的,自然可以协天地之力。

如果你能对一件事物进行合理的抽象,建出合理的模型,自然能在后续工作中游刃有余。

关于DDD一些实践及思考

这些年做了一些DDD项目的建模和重构,算是对DDD有一些心得,在此也想总结下。

是杯子还是装水的容器?

作为DDD的架构师,一定要问自己一个问题:“你开发的到底是个杯子还是装水的容器?”。

“杯子”,顾名思义,已经是一个产品,经过定制的,具象化的一个完整产品。比如用的什么材质?什么颜色等等。

“装水的容器”,更多的是一个抽象的概念,它表示了这种物品的核心功能。

“杯子”是“装水的容器”,但“装水的容器”不一定是杯子。

那么你开发的是什么?

从产品或者业务视角,给你输入的是个“杯子”,他们会跟你说想要一个怎么怎么样的杯子。但是你懂得,今天业务要蓝色,明天可能就要绿色。

如果你是有追求的架构师,不想在一些定制的需求上变来变去,想必更希望抽象成为“装水的容器”,这样当需求有变动时,就可以灵活的扩展。比如换个颜色,换个材质。

如何将“杯子”抽象成“装水的容器”,就是架构师需要做的事情。

如何将“杯子”抽象成“装水的容器”

网上那么多讲DDD的,从来都是讲概念,没有教你如何建模,即使是有真实案例的所谓付费课程,也是一些常用模型,比如“电商”。

电商建模,还需要教吗?都玩烂了,开源代码都有一大堆。订单,支付,商品等等模型已经成熟的不能再成熟(也许有点夸张)。

但是当你进入一个新的领域,该如何着手去建模?

我想讲讲这些年我自己的一点点不是那么学术的经验。

什么是定义

要讲清楚一个领域模型,首先要知道这个领域的定义。

那么什么是定义

百度的

定义是对于一种事物的本质特征或一个概念的内涵和外延的确切而简要的说明;或是透过列出一个事件或者一个物件的基本属性来描述或规范一个词或一个概念的意义。

被定义的事件或者物件叫做被定义项。一般地,能清楚的规定某一名称或术语的概念叫做该名称或术语的定义。

对于一种事物的本质特征或一个概念的内涵和外延所作的简要说明。相当于数学上的对未知数的设定赋值,比如“设某未知数为已知字母x以便于简化计算,”对某个命名的词汇赋与一定的意义或形象,则有利于交流中的识别及认同。

其中很重要的一点就是内涵和外延。

内涵就是“装水的容器”

外延就是颜色,材质。

这里有一篇关于定义讲的不错的视频,可以借鉴下:

https://www.bilibili.com/video/BV1NK4y1x7am/?spm_id_from=333.999.0.0

回过头来分析下杯子

这是网上找到的杯子的定义:

1、杯子的定义:盛饮料或其他液体的器具,多为圆柱形或下部略细,一般体积较小。

2、杯,是盛水的专用器皿,自古以来都是用来喝水或喝茶的,体积一般都很小。或者在古代,喝茶用的杯子叫盖碗。基本形状多为直形或开口形,口沿直径几乎等于杯高。平底、圆脚或高脚。考古资料显示,最早的杯子发现于新石器时代。无论在仰韶文化、龙山文化还是河姆渡文化遗址,都有陶瓷杯。这一时期的杯形最为奇特多样:有耳者为单耳或双耳,有足者多为锥形、三脚架形、高柄杯等。根据材质不同,可分为玻璃杯、塑料杯、陶瓷杯、木制杯等。

我们分析下杯子的内涵和外延,相对来说比较简单

内涵:盛饮料或其他液体的器具

外延:多为圆柱形或下部略细,一般体积较小,不同材质,有盖,有耳等等

可以抽象出这样的模型:

可以这么说

内涵用于确定领域模型及领域能力

外延用于防腐层设计及可替换的能力

一个现实场景例子

杯子定义相对简单,看一个之前在某厂做的具体业务套件的ddd模型

之前给供应链的退供做相关领域模型重构,那么退供的定义是什么

从工作中我们总结了退供的定义:

退供是为了支持经营者确定和执行将货物退回外部合作伙伴的行为。

内涵关键词:经营者、确定、执行、货物、退回、外部合作伙伴

经营者:指业务活动主体

相关外延:租户、用户等

确定:指双方打成共识的动作

如何达成共识:法律相关协议/合同/描述条款文件等等

共识内容:金额、货物、数量

如何确定:创建单据、审批

相关外延:合同、审批流、记账等等

执行:指具体下发退货的动作

相关外延:下发履行、库存冻结/扣减等

货物:指被操作的对象

相关外延:业务模型中的商品信息等

退回:指具体货物/单据的流向

外延:出库履行的回告

外部合作伙伴:指业务活动的去向

外延:供应商/商家等

所以领域模型应该包含:

值对象:

执行信息、履行信息、财务信息(金额、币种等)

实体:

退供单据、经营者、协议(合同)、货物信息(货物ID、数量),外部合作伙伴(供应商,商家)

聚合根:

退供单

当然领域模型是这样,真正对应到数据库的模型也许是这样:

总结

最后讲下笔者之前的工程实践

笔者之前所在团队将领域服务包裹的非常严实,所有的写操作必须通过一个外部的防腐层服务路由,而读服务可以通过防腐层也可以直接从领域服务获取。

防腐层需要保证数据字段的准确性,安全性。用于做一些字段转换,三方数据获取补全等等。而领域服务只会对外暴露基础的读服务。

当有业务需求时,更多的是变更防腐层服务,领域服务是稳定的,领域服务的稳定也保证了领域模型的稳定。

什么时候会动领域服务呢,等业务发展到当前的模型无法支撑新需求时,会重构一个2.0的domianservice,这时的模型也会升级。当然如果领域服务一直升级,那也就说明前期的领域模型建的是有问题的了。

简单总结下

要定义一个领域模型,可以尝试从对象的定义开始。

可以从网上找,也可以找资深领域内人士,把这个领域的关键词抽象出来,组成你自己定义的内涵,然后再一步一步分析得到最终的模型。

当然,这只是笔者的片面之词,ddd如果这么简单也就没有那么多讨论的地方了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值