以下文章来源于丁辉的软件架构说 ,作者丁辉
代码匠艺,软件系统架构,AI平台和应用,生活趣事。
(笔者wo在川知乐 简称老乐)
DDD(领域驱动设计)是目前主流的软件设计思路和方法,特别是现在微服务大行其道,DDD更是被作为微服务拆分的基础方法。和其他设计思路比,其具备整个系统的全局视角,从需求出发,梳理出典型用户场景,实现业务逻辑、系统逻辑和部署逻辑的分析设计,打通问题域和解决方案域的壁垒,提供一揽子解决方案,使得领域模型成为系统演进的核心,从而消除设计和实现之间的mapping,进而获得易于理解、分层清晰、易于维护的软件系统。
两个字搞定DDD设计(领域驱动设计),DDD严重脱水版(一)
DDD,领域驱动设计,是近年来软件设计发展的一个重要节点,软件设计自从软件工程提出以来,先后经历了过程抽象、数据抽象、面向对象、设计模式、设计原则,直到DDD设计,DDD设计的提出主要是为了应对两个问题:
一、降低甚至消除问题域和解决方案域的壁垒
传统的软件设计中,问题域的业务模型与解决方案域的系统模型之间不往往匹配,打个比方,业务模型描述了一堆正方形,而系统模型则是用一堆三角形来表达,虽然两者诸如面积、体积等均相同,也就是说功能和性能实现没问题,但是两个模型的要素和关系的抽象、组织的方式却大不相同,对实现的可理解性带来额外的工作量,而且规模还不小,那就是新增功能和bug修复时都做必须从问题域到解决方案域的转换。
为了应对这个转换,甚至还要引入一个中间层:分析模型,但这也加大了系统理解、维护的复杂度,从而给需求分析、业务架构设计、系统方案设计、编码、测试、部署、升级等都带来了数量级的额外工作量,对软件团队的内在成本影响较大,额外的加班、超额的人力、昂贵的差旅等等根子都来源于此。
二、针对整系统的分解问题复杂度提供结构化的方法
DDD之前,也有很多系统设计的方法,但是往往侧重于问题域或解决方案域一端以及中间连接部分,而DDD提供了一种完整的、端到端的分解设计问题的思路和具体方法。
那DDD该怎么做呢,根据老乐常年使用DDD以及长期DDD教学的经验看,做好DDD设计其实就是两个字:分、合。
当然这个分合是互相关联互相转化的,“分”是手段,遇到复杂庞大混沌的事物,分而治之是不二的手段。
分,是手段。
孙子兵法云:十则围之、五则攻之、倍则战之,敌则能分之、少则守之、不若则避之,这里的敌则能分之就是指尽可能分散敌人,让敌人分兵,使之各部分都变得单薄,然后各个击破,本质就是降低问题复杂度,从而易于被理解和被解决。
合,是目的。
让分后的领域元素和代码元素各司其职,相互协作以成合力。分的要点就是要能够合起来,想当年老乐很小时候就很好奇家里的闹钟为啥会滴答滴答响,一心想把它拆了,后来终于趁乐妈不在家的时候,把闹钟解体了;然而拆解容易,反过来组装起来的时候却多了不少零件怎么都装不进去,这就是个典型只顾拆,不管合的案例,老乐怀着忐忑之心把“成果”给乐妈看,幸亏乐妈没有追究还给了些鼓励,只是以后都偷偷把收音机、唱片机之类都藏到了高处而已。这也养成了老乐遇事都爱剖析、刨根问底的习惯。
所以分合的运用要结合起来看,太极里面强调:上下相随、阴阳相济、内外相合讲的就是这个道理,分之前就要想和怎么合、合的接口要考虑好,分完之后发现合不起来或者合的不自然,那往往不是合本身的问题,一般都是分的不合理。
分的总体思路是高内聚低耦合,这句话有两个含义:关联紧密的事物放一起;仅关联紧密的事物放一起。
其本质思想就是法乎自然,由于事物结合的紧密程度不同,必然会形成一些天然的裂隙,沿着这些天然裂隙进行拆分,请大家注意这个天然缝隙的重要性,沿着它拆分才能得到最自然的高内聚低耦合的分割。
所谓庖丁解牛,找到骨缝和骨肉相连的地方是关键,而不是生砍硬剁,从而游刃有余。
DDD里面的“分”主要分为战略层面和战术层面。
战略层面的分就是从问题域本身进行拆分,把领域拆分成一个个的子域,然后根据对业务支撑程度分为核心子域和其他子域,然后在子域里面再拆分Bounded context,划分bounded context之间的九种关系(合作、共享内核、客户服务、遵奉者、防腐、开放主机、领域语言、分离、杂聚)。然后再从bounded context里面对领域模型进行识别、抽象、组织;如果领域专家和团队对领域知识很精通,那就可以直接通过经验梳理成领域子域和BC、然后把领域概念、关系进行抽象组织即可。
对于新项目等对领域不是很熟悉的,在划分Bounded context时,我们推荐一种结构化的方法:Use Case法,该法基本思路,从系统能力边界的用户出发,找出用户所有的用例,然后把这些用例按照功能接近或语义接近的程度(内聚程度不同造成的天然缝隙)分离,划分一个的bounded context。
划分领域模型时,也给出了三种结构化的方法:
一、对系统领域对象较多,且领域对象间静态关系复杂,推荐CRC(class、responsibility、collaboration)法,通过识别领域概念、领域概念的职责和领域概念之间的协作关系从而给出模型,再通过静态关系图和动态交互图确认这种关系。
二、对于时间强相关的系统,推荐四色建模法,通过MI(时标)、PPT(人、地、物)、Role、Description四个方面,以时间维度为桥梁,自然的揭示出领域模型和它们之间的关系,完成建模,该方法建立的领域模型对业务运营的很多异常流程的支撑都比较适合。
三、对于动态协作比较多的系统,推荐事件风暴建模法,以领域事件为核心,通过事件、命令、领域概念展示系统动态协作关系,从而建立领域模型。
综上,DDD建模战略建模的过程就是“分”的过程,通过一系列的结构化和非结构化方法,把一个一堆杂乱纷杂的大需求拆分成一套完成的领域模型(领域概念和概念关系),并使用主要业务流程对这些领域模型进行验证,看看它们是否能完整支撑主要业务场景,
挖个坑,下一步,我们将进入战术建模阶段,把这些领域模型(概念和关系)合入DDD的分层建构和6个核心概念中,让它们互相协作,产生合力(待续)。
往期推荐
技术琐话
以分布式设计、架构、体系思想为基础,兼论研发相关的点点滴滴,不限于代码、质量体系和研发管理。本号由坐馆老司机技术团队维护。