这是【一文一点】的第8篇原创文章,不拘泥于篇幅字数,用一篇文章说清一个知识点。
答案是:通用语言和模型驱动。
1、
所有的软件最终是要解决用户问题的,而软件的落地最终是要靠一行行的代码垒起来的,那么这个时候从识别出用户问题到代码实现之间就需要一种过度,而架构设计就是这种过度的【桥梁】。
DDD是架构设计的一种方法,在DDD中的模型驱动设计里面有两种设计方法,一种是战略设计,用来识别用户问题,一种是战术设计,用来指导落地问题的解决方法。
因此DDD是可以担当起建设那座桥梁的重任。
2、
如果要对DDD所要干的事情分类的话,可以分为两类,一是建立通用语言,二是进行模型驱动设计,其中在模型驱动设计中又包含战略设计和战术设计。
通用语言的介绍,我在上一篇文章里面有介绍过,就是要有一个可以描述业务事物,也可以描述技术人员理解的事物,拉齐业务人员和技术人员的语言,减少他们之间的沟通成本。
要做这件拉齐的事,一般情况下,我们可能会这么干,业务人员和研发人员坐在一起聊,其实,无论怎么个形式,都得聊。
可是呢,聊也最好有个聊的形式或者组织方法,这就有了DDD中的事件风暴。
给这种组织方法做个类比的话,可以参考敏捷团队的实践。
大家如果参与过敏捷团队组织的话,比较好理解这点,进行敏捷实践的时候一般有好几个会,比如需求梳理会,迭代计划会,以及还有敏捷物理看板,种种这些都是建立在一种组织过程方法上,在这个方法中呢,我们就把需求梳理出来,计划会上把任务确定下来,物理看板把任务流动起来。
如果在具象一点的话,事件风暴是一个参与式工作坊。
如果理解了参与式工作坊是干啥的,其实我们就能够理解事件风暴了。
按照《工作坊》这本书的介绍
“参与式工作坊”是一个多人数共同参与的场域与过程,且让参与者在参与的过程中能够相互对话沟通、共同思考、进行调查与分析、提出方案或规划,并一起讨论让这个方案如何推动,甚至可以实际行动,这样“聚会”与“一连串的过程”,就叫做参与式工作坊。换句话说,工作坊就是利用一个比较轻松、有趣的互动方式,将上述这些事情串联起来,成为一个有系统的过程。
所以,事件风暴是一种工作坊的形式,在这个过程就是要建立业务与研发人员,在描述需求事物上的通用语言。
下面这张图是我从网络上找的,它所展现的这种形式就是我们进行事件风暴工作坊期间的产出,通过这种工作坊把业务和研发人员拉在了一起,冲破了业务和研发人员之间的”那堵墙“。
图自网络
3、
这种工作坊,除了建立通用语言以外呢,还有一件事,那就是要识别出领域事件,因为毕竟人家叫做事件风暴嘛。
那么什么是是领域事件呢,举一个京东商城的例子,作为一个商家,他的业务场景之一就是发布商品,那么这里的领域事件就是商品已上架。
作为一个C端消费者,他的业务场景之一就是购买的商品是否发货成功,那么这里的领域事件就是已发货。
所以估计大家看出来了,领域事件所描述的就是动作发生之后的结果,反映到代码描述上就是一种动作的过去式。
图自网络
4、
我们再来看模型驱动设计里面的战略设计和战术设计。
战略设计,属于高层设计,这里的高层是相对于抽象和具体来说的,到了代码层面那就是具体,在抽象层面那就是高层,我们抽象的是什么,比如订单业务模型、商品业务模型等等,这些模型就是我们抽象出来的。
领域驱动设计里面的【领域】两个字,透露出了一种【范围】意识,这也就是我们经常在DDD中强调边界的原因,因为范围本身就有边界的概念。
再联想到微服务设计要按照功能来进行拆分,这也是为什么DDD能够很好的指导微服务建设的原因之一,它们都强调了【边界】。
这种范围或者边界,对应到DDD中就是域,比如我们已经建立的订单业务模型和商品业务模型,也变成了订单域和商品域。
那么战略设计最重要的是要干什么呢,我认为就是为了“归堆”,象上面我们说的边界也好,范围也好,乃至【域】也好,都是为了进行分组,当然,DDD中还有个更专业的词,限界上线文。
图自网络百度搜索
5、
如果说战略设计是站在高层来识别问题,识别范围或者边界,那么战术设计就是来进行解决问题的了,毕竟,软件设计也好,架构设计也好都是要解决问题的,正如我们文章刚开始的时候说的,架构设计就是业务问题和解决方案之间的桥梁。
DDD有了战略设计来识别问题,然后通过战术设计来落地解决问题的方法,自然DDD便担负起了桥梁的角色。
在战略设计中,我们已经识别出来了业务域,比如订单域,那么该怎样映射到我们的设计上呢,这就是战术设计干的事情。
战术设计中有很多个DDD概念,实体、值对象、聚合等等,关于这部分知识大家可以参看《实现领域驱动设计》这本书,里面都有更详细的介绍。
我们这里简单描述一个例子,比如京东商城上面的订单信息,它有一个订单号,来表示唯一,另外它还有其它的属性,订单金额、下单时间、出库时间、购买人等等,订单号永远不会变,但是其它的属性有可能会变化,比如出库时间可能会因为库存问题而发生变化。
这里的订单就是一个有订单号来表示的实体。
一个订单里面,可能会包含很多个订单项,比如一次购买了3件不同的商品,那么手机是一项,耳机是一项,笔记本是一项,这些项目分别都会一个商品ID。
这里的订单项就是一个值对象。
在战术设计中就是通过类似上面的方法,把战略设计中识别出来的订单域进行了一次【过度】,进而更贴近了代码的语言,并最终实现当初的订单域中所需要的功能。
6、
最后。
我们也常说没有银弹,或者没有双利解,DDD当然也不是双利解,更不是银弹,但领域驱动设计目前在大多数业务场景中都能很好的被使用,这足够了。
关于学习DDD的方法,亘古不变的真理,理论结合实践,理论的知识我们可以通过阅读书籍,比如《实现领域驱动设计》,实践呢,就是要我们在工作过程中去不断的尝试了。
都说师傅领进门,修行在个人,如果你是DDD的初学者,那么首先有个知识的框架就再好不过了,这方面推荐郑晔老师在极客专栏《软件设计之美》中的关于设计一个软件的软件设计方法中所讲到的三篇文章,大家可以去看下。
我又写完了一个知识点,如果你看到,觉得有一点帮助,点再看分享给更多人。