DDD-实战解析

247 阅读16分钟

如何成为优秀的架构师?

我只要技术牛、技术好就可以成为优秀的架构师

是否是技术大牛就能成为优秀的架构师?架构师=技术大牛?

光知道技术并不能成为真正的架构师,优秀架构师和技术大牛到底差别在哪些地方?

架构师不仅要懂技术、还要懂业务,只有将业务落地到技术,开发出用户有价值的产品,那么技术才是有价值的,而技术大牛只懂技术,不能将业务痛点用技术的方式帮他解决,那么我们的技术才会有价值,优秀的业务架构师,能将业务的痛点转化为技术实现,这样才能体现我们是优秀的架构师。

架构师本质

架构师要能将业务转化为技术

架构师能合理运营技术支撑业务

客户买单买的不是技术,而是用技术解决他们的问题

对业务及其痛点有深刻的理解与思考

➢分析业务流程

➢理解业务规则

➢挖掘业务痛点

能够将技术落地产生业务价值

➢规划高远却落不了地

➢快速研发产生业务价值

成为优秀架构师关键难题

  • 如何快速有效地学习业务领域知识
  • 如何深入地理解与挖掘业务痛点
  • 如何通过技术的手段落地业务

产品技术方案都是为了解决业务痛点,必须要认真掌握、深刻思考,架构师不仅要理解,甚至会比业务人员、产品理解都要深刻。这些业务痛点如果运用技术手段去解决

前面的问题基本都是架构师面临的真正的问题,在我们的架构师团队、其实我们不缺技术,我们都是技术领域的专研者,但是正真的弱项在于业务,在于我们理解业务,理解业务痛点

如果通过一些方法快速理解业务,从小白成为业务专家,指导我们设计开发我们的系统,这时候我们需要一些知识一些技术一些方法来指导我们做事,而这个方法是什么呢?就是我们今天要说的DDD领域驱动设计

今天先不谈技术,先谈业务,最有效的方法是什么呢,就是领域设计,而领域设计越来越火,越来越多的团队开始尝试做这个事情,为什么领域驱动开始火起来了呢,有的人任务是微服务的发展需要领域驱动,也有人任务是需要建设中台需要领域设计,但是我认为这些想法都不够深刻

image.png

大家看看这本书的副标题,领域设计在什么时候对我们帮助最大呢?就是我们的软件核心复杂性应对之道,软件越复杂越难以理解的时候,假如系统没有那么复杂,那么我们需要领域驱动吗?恰恰相反,当我们的系统没有那么复杂的时候,反倒领域驱动倒有一些麻烦,有一些累赘,所以正因为这个原因,我们的领域驱动没有发展起来。在简单的系统里没有享受到领域驱动带来的好处,这个时候就有一些团队在开始动摇了,反而觉得领域驱动没有那么爽,这就是我们领域驱动没有真正认识到它的作用。

为什么需要领域驱动?

在新项目开发中起作用吗?

在老项目维护中起作用吗?

在技术架构演化中起作用吗?

这是大家值得思考的问题。

这么几个问题?大家觉得哪个是领域驱动真正的起作用?

领域驱动在新项目中起作用吗?

开始就需要领域建模,领域建模的过程中就要深刻的理解业务,把业务转化成领域模型,再将领域模型指导我们的数据库设计、程序设计,转化成程序设计的时候,我们还要按照贫血模型或者充血模型的设计思路转化成我们的程序设计,这个过程也有很多的学习成本,而我们的新项目中往往的特点

  1. 新项目的复杂度并没有那么高
  2. 我们在新项目里最着急的要快速的把系统上线,把系统用起来

在这个时候使用领域设计反而会变得非常累赘,非常麻烦,没有那么直接,因此很多的团队一开始就在新项目就用领域驱动,因此,我们的领导或者其他的团队就会问,你们用领域驱动设计怎么样啊?用的好不好?能不能提高我们的开发速度?在面对这些问题的时候,我们很多团队就懵了,它感觉好像我们在开发新项目的时候,这个领域驱动好像并不是那么好用。

但是当我们的新项目上线了,在维护老项目

在老系统上不断的运维

最初的项目,就只有那么几个功能,并不复杂,很快就可以上线,新项目上线后,逐渐逐渐的变成老项目,在老项目里我们要不断的添加功能,不断的在上一个版本的基础上做迭代,做更改,这时候我们的代码就越来越复杂,设计就越来复杂,系统的规模就越来越庞大,这时候我们发现我们的项目已经不像最初的那样有效的开发和维护我们的系统,这样,我们的系统维护起来越来越慢,设计起来越来越费劲,我们的设计就开始迷失方向。当我们面对老项目越来越难维护,什么方法能帮助我们更好的去设计,这时候领域驱动才是该上场的时候,领域驱动什么时候能更好的更有效的发挥出来呢?就是我们的系统变得越来越复杂,越来越庞大的时候。

领域驱动的设计在日后的维护中能体现的更好,理解这个,那么在新项目设计的时候使用领域驱动,有点麻烦,但是你也能理解,我们的麻烦不在于现在,而是为了将来

未来的项目也不会因为越来越庞大而难以维护。

未来业务不断迭代

未来市场激烈竞争,要求我们快速交付

未来技术快速更新

不断庞大系统,而又要快速交付新产品,最有效的就是领域设计

领域驱动的解决之道

业务负责人/产品经理以故事的形式把我们未来要做的功能分开给各个敏捷团队,每个敏捷团队呢都是一个功能模块去做我们的各个模块的设计开发,每个敏捷团队在开发的过程中两个事,第一是领域驱动设计,第二个是架构设计,把一个大规模的系统拆分成多个微服务,各自独立的设计开发我们的系统,在微服务架构拆分微服务的过程中非常需要领域设计,站在业务的角度来分析整理,来决定我们的微服务的划分,为什么需要领域驱动设计来指导我们的微服务划分呢?这个地方很关键

image.png

以往烟囱式的数据库设计

image.png

每个模板有自己的表,每个模板通过jdbc访问对应数据库表,这个时候如果商品表有变更,那么所有的模板都会变更,这个就是没有通过领域设计而又采用微服务架构带来的问题,这个时候什么样的微服务设计能满足业务需要呢,如果某个业务变更,她的变更只会落到一个微服务上,这样就只需要把这个微服务升级就行了,并不影响其他的微服务,因此我们在设计上就要做到小而专的设计

小而专的微服务设计

小指的就是拆分微服务,专是什么呢?就是单一职责原则,以往很多微服务设计往往只专注了小,而忽略了专,那么怎么才能做一个小而专的微服务设计呢?那么我们要求在我们数据库中的所有表只能有一个微服务对它进行读写,而其他的微服务要读取这个表的数据呢,只能通过通过接口的形式相互调用,那么我的变更只会对我的微服务有影响,对于其他的微服务呢,由于我接口没有变更,所以没有影响,那么怎么做到小而专呢?我们首先要对数据库进行规划,哪些表属于哪个微服务,提高我们的内聚度,提高我们的设计质量,就要从业务的角度进行分析整理划分我们的系统。在业界最有效的就是通过领域设计。把我们的系统按照限界上下文的形式就行拆分

image.png

按照这样的设计思路,我们把表分开,可能还会跨库,这样就会有另外一个难题,跨库关联查询难题

跨库关联查询解决方案

image.png

采用这种方式,每次写代码都要补填,查询起来很麻烦,需要写很多代码,这时需要一个底层,通过一个支持领域驱动的这样的技术平台把这些问题,这些数据补填的问题都封装在这个平台里,有了这个平台后,我们在设计开发的时候,我们只需要去按照领域模型进行建模,在领域模型建模的过程中,我们建立好他们之间的相互关联关系,比如订单里有用户有饭店,通过哪个字段进行关联的,在业务开发的时候,我们只需要把这些关联的关联关系配置好,那么剩下的时间,我们在查询的时候,我就查订单表,但是在查询订单表的时候,我们通过底层自动的把用户信息、饭店信息进行了补填,今后的业务开发,我们把更多的精力放到专注于我的对业务的分析,对我们建立领域模型,建立对象之间的关系,把这些关系落实到设计开发,落实到我们的领域模型设计,剩下的这些事就交给底层

解决的难题

领域驱动设计的作用与意义

怎样正确地进行业务领域建模

怎样将模型转换为程序设计

支持领域驱动设计的架构设计

怎样正确地进行业务领域建模

按照领域驱动设计和不按领域驱动设计的差别?

未来趋势 物联网+人工智能/ 系统会越来越庞大

image.png

比如电商网站付款功能

image.png

最开始设计的代码还是比较清晰,但是随着系统的运营,慢慢会出一些相关的功能,比如打折

image.png

还会增加VIP会员,增加支付,增加秒杀,闪购,返券等

image.png

维护起来就越来越困难,为什么在维护系统的时候会越来越乱,越来越难以维护呢,这是软件发展的必然规律,因为软件是真实世界的模拟,而真实世界又是很复杂的,所以在认识真实世界的时候是需要一个过程,我们只识别了那些真实世界里简单明了的业务逻辑,做到我们的软件里,因此我们会发现第一个版本我们开发的软件都是简单清晰明了,但是在系统上线以后,用户就会发现还有很多不简单、不清晰、不明了的那些业务没有在我们的系统里,他就会提bug、新需求。我们发现在我们修改bug,开发新需求的过程中,我们的软件才会越来越接近真实世界系统的规模会越来越大,我们的业务逻辑就会越来越复杂。

image.png

简单软件和复杂的软件

image.png

软件的退化不是需求变更

image.png

领域模型和领域模型建模思想

image.png

需求变更、增加折扣

增加商品折扣功能

限时折扣

限量折扣

对某类商品进行折扣

对某个商品进行折扣

不折扣

以往不冷静,直接开始编码

image.png

付款的时候有折扣、可能就会写到付款的代码里

image.png

单一职责原则(SRP)

软件系统中的每个元素只完成自己职责内的事,将其他的事交给别人去做

什么是职责?

错误的说法:“职责”通常人理解为一个事情,与该事情相关的事都是它的职责

正确的:一个职责是软件变化的一个原因

高质量的软件?关键是我们的维护成本

当来了个新需求,我们维护成本越低,那设计质量就越高,如果来了个需求需要改动3个模块的代码。我们就认为质量就是低,每次来了新需求我们只改一个模板的代码,我的设计质量就高了。维护成本就会低。就要要求我们平时就要不断的整理我们的代码,将代码里软件变化同一个原因的代码放到一起,软件变化不同原因的代码分开放,这样今后因为这个原因而发生变更,我们就只改这个模块的代码,就和其他模块没有关系,这样的话我们的维护成本就降低了

折扣变化是否会引起付款变化、付款变化是否会引起折扣的变化,这样分析那么折扣的代码就不应该放到付款里。同样限时折扣是否会影响到限量折扣。回答都是否定,说明每种折扣都是软件变化不同的原因,所以我们应该放到不同的模块里,基于这样的思路。

image.png

界限上下文

image.png

image.png

什么时候需要领域驱动?

案例:远程智慧医疗系统

前身:

诊所管理信息系统

  • 传统管理信息系统
  • 采用传统技术架构

互联网转型

互联网诊所管理系统

  • 加入连锁诊所管理
  • 加入互联网远程接诊
  • 向互联网技术架构转型

智能诊断治疗信息系统

  • 加入人工智能数据模型
  • 辅助医生智能诊断治疗
  • 向大数据技术架构转型

期初:传统的诊所管理系统

image.png

统一语言与领域建模

image.png

客户清楚的知道他的业务,但是他不知道怎么来解决,而我们清楚的知道技术,但是不知道业务是怎么样的,不知道怎么设计,所以我们需要知道他的业务痛点,所以我们需要统一语言,用他的语言来表达他的需求,客户就可以感觉我们越来越懂她的业务。越来越愿意和我们交流

事件风暴(Event Storming)

事件风暴(Event Storming)

是一种基于工作坊的实践方法,它可以快速发现业务领域中正在发生的事件,指导领域建模及程序开发。

它是Alberto Brandolini发明的一种领域驱动设计实践方法,被广泛应用于业务流程建模和需求工程

基本思想是将软件开发人员和领域专家聚集在一起,相互学习。

为了让学习变得更容易,该方法的工作方式类似于头脑风暴,让事件风暴变得很有趣

事件即事实(Event as Fact)

领域事件:即领域中发生的事实(fact)

在真实世界中,当满足某个条件时,某个发起者会触发某个事件,做某个事情

事实(fact):

是指那些已经发生过的事件。

鉴于过去已经发生的事实不会发生改变,因此信息系统可以将这些事实以信息的形式存储到数据库中,即信息

就是一组事实。

事件风暴会议

有一个大的白板,还有一个五色的便签纸

image.png

1、事件风暴会议以完成领域模型为目标

2、参会人员:领域专家和软件开发人员

3、会议以探讨领域事件开始,从前往后依次梳理,以确保领域中所有事件都能覆盖

4、项目组成员不断增加各种命令与事件,进而思考与之相关的资源、外部系统与时间

5、识别模型中可能聚合及其聚合根

6、将模型分配到各个界限上下文中,构建上下文地图

分析诊所系统的领域事件

image.png

领域事件的命名都是过去式

image.png

已开药和已确诊属于同一功能一次性完成,没有必要分成两个领域事件,查找医生是否是领域事件呢?什么是领域事件,是过去已经发生的,但是事情很重要,需要记录,这才是领域事件,查找医生的一个查询,而查询不一定要记录,记录的最后预约了,所以查找医生不算领域事件。

image.png

事件的橙色的,命令是蓝色的,黄色代表相关的人和事

image.png

紫色代表聚合关系,聚合关系不要搞错了。

什么是聚合关系?

。。。

领域建模——患者预约

image.png

领域建模——医生接诊

image.png