本篇内容:谈谈自己和身边的人学习领域驱动设计的路径和思路,提出自己个人觉得快速学习路径。
DDD 学习有那些难点:
1:网上资料少,基本都是关于原理方面的描述,几乎无较好的实战模版参考。
2:DDD 目前来说还是比较小众的,学习群体不是很多。
3:在实际的互联网项目中,DDD 基本处于战略设计阶段,战术落地的基本都在摸索过河。
我个人的经历:
我自己是非常幸运的,N 年前就开始接触 DDD,而且还有级别很高的大佬带着做项目,我很感激我的 DDD 启蒙老师,把我带进了门。
后来的工作经验中,我也是很幸运的,几乎每个公司的项目,我都一直努力的用 DDD 去实战,而且公司领导都很支持。
从最初用 DDD 做战略,到后来慢慢独立用 DDD 做战术,到后来自己整理倡导实践 DDD,我最大的感受就是幸亏 N 年前有贵人带我入了门,也幸亏 N 年间大大小小项目一直坚持使用 DDD 在实战。
朋友们的经历:
和一些朋友聊过学习 DDD 的经历,很多朋友吐槽,最大的难点主要在于两点:
书上和网上的资料看不懂。
书上和网上的资料看的懂,觉得说的非常有道理,但实战落地时无处下手。
针对这两点,我的看法是这样的:
对于看不懂的同学,建议有两条路子:
1:找个好的启蒙伙伴作为 DDD 的引路人,这个启蒙伙伴最好长期处于 DDD 代码一线实战的同学。
2:暂时不要看了,先认真的做好公司现在的业务,多做多想,主要是想我现在做的业务是什么,能干什么,和其他业务的边界是什么,等你对当前所做的业务了解很透彻后,你再回来看看 DDD 的经典书籍,很有可能你就会变成第二类人了。
当然还有第三种,不停持续的看,俗话说书读百遍其义自现,但我现在还木有遇到过这样的高手,所以不推荐。
对于看什么都觉得有道理,但 DDD 实战落不了地的同学,有如下建议:
1:敢于跨出第一步,非工作时间,自己尝试使用 DDD 战术重构你目前在做的业务,跨出第一步最重要。
2:建议多和朋友交流 DDD,火花很多都是碰撞出来的,如果网上有稍微成熟的 DDD 战术 demo 可以参考那就更好了。
其实我自己是幸运的,幸运有个好的 DDD 启蒙老师,也感谢公司领导允许我使用 DDD 落地公司项目,有好的机遇和环境真的非常重要,别人搞几年 DDD 理论,还不如你用 DDD 搞一个实战项目理解的深。
其实我这里还有最快的学习方法!
大家一开始在学习 Java 的时候,大学老师可能会说,不要问什么,先跟我写一个 Hello World,应该没有同学一开始就去学习的 HashMap 的链表为什么在长度大于 8 的时候转化成红黑树,去学习锁的等待队列和同步队列如何实现的,去学习如何 debug JVM 这么高深的东西吧?
所以我一直以为,写代码的同学想入门学习新知识,先不要去学原理,show me code 才是最好的老师!如果 code 没有坏味道那就太棒了。
所以我认为最快的学习 DDD 的方法,是先搞到比较好的,经历一线开发的 DDD 代码 demo,把自己最熟悉的业务,按照这个 demo 走一遍!在写代码的过程中,请你务必不断的问自己三个问题:
1:代码的位置对不对(考虑分层,命名)
2:代码能不能这样写(考虑类,方法的职责是什么,边界是什么)
3:和 demo 做个对比,想想为什么我写的和 demo 的不同,那个好那个坏,和 demo 作者讨论讨论。
我相信,只需要一遍下来,你肯定对 DDD 有不一样的认识!
理论知识也不可少!
如果你搞到的 DDD demo 代码质量比较好,那么恭喜你已经能模仿写出神似 DDD 的代码了,这时候就要去去想想代码为什么这么写了!
就好比我们学习 Java 一样,刚开始的时候我们不断的使用 Java 的 API 去写 if else, 当你都熟悉之后,你就会去看看 Java 源码了,看源码过程中,你会感觉到 Java 原来如此美妙,感叹 Java 的设计之美,原来我以前那么用 api 是不正确的,接着你可以把好的记下来,复制成自己的,再去公司的项目中去练习!这就是复制粘贴,学习 DDD 同样如此。
所以综上,推荐最快的学习路径图:
落地时有那些坑
1:不要一个人琢磨 DDD,找个比你厉害的朋友一起。
2:DDD 一定要找个业务场景练手,如果你只是看,那你可能一直学不会,DDD 写过的和没写过代码的同学思维相差很大。
3:总结出自己的一套 DDD 业务框架真的很重要,因为你的老板不会因为你牛*的 DDD 原理而给你加薪(搞研究的的除外),看中的是 DDD 给生产带来的效率。
4:实战 DDD 不是一步到位的,可能当你练手十几个项目之后,才能总结出自己的套路,所以不要着急。
5:落地时不要过分强调战术,我们应该强调战略,应该把60%左右的事情花在战略建模上,而不是战术。如果领域模型体现不了业务,战术又有什么用?
我们曾经草草建立领域模型,把大多数时间画在实战上,最后我们发现代码很厉害,但却不是客户想要的,等于白做,毫无绩效!
6:不要强推 DDD,我们曾经在大领导的带领下,强推 DDD ,但理解和懂 DDD 的同事很少,大多人都不知道 DDD 如何领域建模,如何落地,核心同事带领 DDD 落地后,维护比较难,几个月后,项目又变成了 MVC 的形式。
我个人推动 DDD 的经验是:1:和领导保持默契,适当时机常提 DDD 的好处,得到领导的支持 2:在公司内部多搞培训,多多宣传 DDD 干货,让周边同事对 DDD 认可,感受到 DDD 的威力 3:选择公司小中型项目,和同事一起进行战略落地,让同事感受到 DDD 的魅力 4:选择大中型项目,带领感兴趣的同事一起全程落地 DDD。慢慢的,你会发现公司同事都在讨论 DDD。
7:不要在技术项目上推进 DDD,DDD 是一种业务框架,在技术框架上是发挥不了威力的哈。
8:DDD 落地框架使用方式上最好符合主流技术架构,不要使用比较特殊的方式,让同事们觉得使用起来很别扭,比如我们都用 Spring IOC,新的 DDD 框架却完全不同,你应该也不想每个人都过来问你:为什么不用 Spring IOC 吧?
9:好的 DDD 框架一定不会让同事觉得使用别扭,也不会让开发总是去关注框架本身,如果只让开发只写写 if else 的逻辑,最好不过了。
10:DDD 的代码真的不怎么重要,重要的是有过一线实战的 DDD 思想,你会发现工作中到处都是 DDD 的影子,只是我们原来不知道他叫 DDD 罢了。
11:DDD 战略设计时,请先抛开技术实现,但也不要完全不管,毕竟不同公司技术能力还是不同的,有时候还是要向技术妥协。
写了这么多,我最想说的其实是:DDD 原理很重要,但老板不会因为你牛*的原理给你加薪,DDD 快速落地才是关键,并且能给生产带来效率,当然如果对 DDD 原理都比较模糊的同学,也不可能写出属于自己的一套业务框架,所以你还在等什么,赶紧下载代码,复制粘贴学习起来吧!
本文主要聊了下我个人对 DDD 的学习看法,当然可能也不适合你,其实最好的方式就是找个有多年一线 DDD 实战经验的朋友,搞一份实战代码过来学习,毕竟代码是最好的老师!
接下来我们来解答下上次发文后留下来的几个问题吧:
上次我们聊了聚合,文章地址:https://mp.weixin.qq.com/s/WTGO9xzvfyn-wrbFuyzkgA
留下来几个问题,我们讨论下,对于聚合概念模糊的同学可以再看看文章。
1:下单人黑名单校验 是不是聚合?
下单人黑名单校验,我们可以抽象成黑名单校验,我们在聊 DDD 的时候,尽量去掉人的干扰,不然你会觉得所有的东西都和人有关,这是一个动作,不符合聚合的定义,所以不是聚合。
2:拆单 是不是聚合?
拆单的解释是:当买家把多个店铺的不同商品加入购物车,一起支付时,需要根据店铺和商品的不同属性进行拆分,生成多个订单。
正常下单流程如下:
拆单场景:
上面画的两个图,其实也是一个思考的小技巧,特别是复杂场景的时候,当你想不通拆单是什么的时候,可以先画一个正常不拆单的图,然后再画一个拆单的图,这样做的好处,是方便你想全需求,对拆单是什么能想的更清楚。
有同学可能会想了,拆单是一个动作,挂不到任何一个领域对象头上,那我就直接当作一个领域服务吧,于是在下单的流量打进来之后,我们在 app 层直接调用拆单这个领域服务,代码如下:
大家有木有觉得有点别扭?
如果现在来了这么一个需求,有个零售大商家 A,商家 A 是卖家电的,为了冲销量,强制规定,用户下单的每个商品都要拆成一个订单,也就是说一个订单下面只能有一个商品,这时候代码怎么写?
可能为了代码匆匆上线,有同学这么写:
代码review的时候,可能有同事说了,这样写不对的哈,怎么能把 if else 的逻辑抛给 app 层去做呢,应该写在领域服务的里面,于是代码改成这样:
app 层代码还原
if else 逻辑移到了领域服务 SplitOrderServiceImpl 里面,如下:
随着业务的增加,这个领域服务的 if else 逻辑越来越多,有同学说搞个规则引擎吧,于是开发了一个规则引擎解决了 if else 逻辑过多的问题,技术上一切来看都很美好,可真的如此么?
我们先抛开技术实现,再来认真审视一下拆单这个业务:
我们可以看到,左边业务方的场景多变,导致了拆单的需求,而右边又只提供单个通用的订单创建服务,这时候怎么办?
是时候讨论一下业务的归属了!
拆单业务的产生是因为上层业务方复杂多变的需求导致,是业务方关心的业务,所以拆单的业务归属应该属于业务方,所以一开始就由下单来做这个事情可能就不是特别合理了,业务归属弄错了,做了再多,可能还是错的。
优化之后可能就这么实现:
那随着业务的发展,可能就会有人发现,左边的业务方越来越多,每个业务方都会去实现拆单的功能,而拆单有些逻辑可能是可以被复用的,于是架构师们通过调研,决定我们其实是可以搞个拆单平台,专门负责各个业务方的拆单任务,注意这里的是平台,平台关心业务方的业务是没有关系的,于是架构演变如下:
以上内容主要想说明两点:
1:当一个新的业务到来之前,请确认业务本身是什么,业务之间的上下文边界是什么,这就是 DDD 中常说的上下文边界,只不过这里的上下文边界的对象很大,是一个拆单业务。
2:整个思考过程体现了架构的演变过程,任何架构都不是一下子就到底的,需要根据业务的发展和成本进行,当然这个实现并且不是真实的实现哈。
图片中代码都在老地方,DMVP 星球伙伴们可以尝试自己写写拆单场景的代码,如果是你,你将如何实现?
END
贴上广告
微信公众号二维码:
DMVP 知识星球二维码:
DMVP 介绍: