DDD到底该怎么落地,代码到底该不该从MVC转到DDD

本文是个人理解,并不一定准确,仅供参考,想吐槽也可留言

一、我理解的DDD有什么好的地方

第一:统一语言真的很重要,一定要把这个术语的中文,英文落实到文档,不管是老员工还是新来的,还是代码开发、字段定义等等都要保持一致,这样即便新人,或者不懂技术的人看到了这个单词都能知道什么意思,业务,产品,开发,测试、、、所有相关人员说起话,聊起来才没有障碍,没有歧义

第二:领域建模,领域划分

        这块还真不是一般人能搞的,首先如果你对该领域并没有那么深入的理解,真的需要一个特别懂的人(如果团队没有这么一个人,那真的不应该做这个业务,先去熟悉业务吧)如果这个人即是领域专家,又懂技术,那这个人就是最适合做建模和划分的,这个人一般是架构师或者牵头的人;

        如果这个人只是领域专家,对业务相当熟悉,但不懂技术,这个时候就要找个技术和沟通较好的去跟领域专家沟通然后产出一个领域建模,并且要让所有参与的人看的懂(这个很关键,必须所有人都能看懂)

        有了领域模型接下来要做的就是将这些模型做一个边界,也就是领域划分,先划分大的领域,再划分子领域。本质上就是:保证模型概念的清晰和无歧义,避免有多重概念和职责的模型,也就是在微服务的拆分粒度上下功夫,当然如果业务初期也可以不拆分微服务,按包区别领域也行;我理解这就跟我们做概要设计一样,找到领域边界、关系,反复评审修改后达成一致就可以针对领域做详细设计了

第三:服务

        服务包含领域服务和应用服务

        领域服务:主要负责处理该领域的业务

        应用服务:主要去组装业务也就跟我们平常的服务编排差不多,应用服务不去关心领域服务的复杂性,只关心业务的复杂性

回想DDD领域驱动设计,大概就是彻底理解业务领域后进行设计,然而这个彻底理解业务也并不是一件容易的事情,我们可以通过领域专家或者“事件风暴”来探索复杂领域,这个时候就体现出懂业务的重要性了,我一直秉持的理念就是:不了解业务写不出高质量的代码

二、代码到底该不该从MVC转到DDD

代码层面是大多数开发者最关心的,我之前工作种就一家公司代码看到了DDD的影子,而且还只是影子,其它全部是MVC模式

MVC:这个我们太熟了Controller依赖Service依赖dao,复杂的业务全在service里写,这个我们太熟了

例如:有个订单服务:

1、校验参数
if(Objects.isnull(obj)){
    return null;
}
2、金额校验
//是否有优惠券,调用优惠券计算
//计算订单金额
if(判断订单金额,如果有问题){
    return;
}
3、插入订单表
4、调用支付,支付金额
5、修改订单表状态
6、通知快递
7、发送短信
8、、、

这样的服务我们是不是很熟悉,如果有一天产品加了个参数校验逻辑,只需要加个if,如果有个需求需要按一定算法去算金额,只需要加个if,后期需求越来越多,if也就越来越多,不断的兼容,坏味道也就越来越重

这只是一个service服务(聚合服务),针对这种有什么优化方式呢?

1、订单的校验操作可以放到订单实体里,统一暴漏,多处应用,修改的时候只需要修改一个地方

2、订单相关的金额加减算法可统一维护到实体

3、新建订单,修改库存,等这类需要保证事务的操作可写一个聚合服务,保证聚合服务内数据一致性

4、通知快递,短信,push之类的可通过事件驱动,比如发送mq

5、金额计算,支付,优惠券计算可以下沉到对应的领域服务去做

这样写下来,后期要修改需求,这个聚合服务一般不需要动,只要去修改相应的领域服务,或者实体,聚合即可

上面说的只是单个服务的优化上,只要用好设计模式,理解设计原则基本都能做的大差不离,但往往事与愿违,代码总是在不知不觉中堆成了山

之前写过一个定时任务的服务,利用模板方法和策略模式将类似业务模板化,哪怕是刚毕业的小白也能通过cv写出一个标准的代码,当然水平高的也就无法发挥自身了,根据这种思维,我们可以将代码格式进行优化,按规定将代码固定写在要写的位置

引用链:

app->infrastructure,trigger;

trigger->domain,api;

infrastructure->domain;

domain->types;

api->types

1、app层-主要进行全局配置,比如xxl-job,mq,redis,全局异常,日志等等,依赖infrastructure,trigger

2、infrastructure-基础设施层,封装第三方依赖,比如依赖优惠券可以写在gateway里,比如依赖redis等

3、trigger层:接受外部的请求比如:http请求,job,mq,rpc等,进行领域的简单聚合,依赖domain

4、domain层:也就是我们的领域层,也就是我们写领域服务的地方,adapter可以定义一些依赖第三方的接口,repository可以定义操作数据库、缓存、mongo等的接口,model主要定义各种实体,值对象,聚合对象等,service写我们的领域核心服务,注意领域内不能相互调用要调用必须通过在adapter定义接口这种方式,注意这里是使用依赖倒置原则,只定义接口,由infrastructure-基础设施层实现,好处就是如果数据库由mysql换成mongoDB就只需要改基础设施层即可,领域层无感知

5、api层:对外暴漏服务,提供协议,供第三方引用

6、types:提供一些常量,枚举,公共返回等不依赖任何模块,可以被其它模块引用

三、总结:

即便这么设计了分层,也不能保证百分百代码不烂,写代码的时候只顾一贯的堆,不理解设计模式,设计原则,很难写出优秀的代码

经过这么多年的经验,只要能熟练使用模板、策略、工厂、单一原则就能解决80%的代码问题

最后该不该从mvc到DDD呢?我觉得还是应该做

我们宁可不要大牛的自由发挥,也要限制小白的自由发挥

后期再进行间断性的代码review,不断改进,养成习惯,就成功了一大半

  • 24
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值