领域驱动设计:从学习到实践(一)

简介: 产品同学将需求分析完和开发同学进行需求评审,评审完毕后开发同学开始基于需求进行设计,一般会落到数据库设计,将库表设计完毕后,再向上进行分层开发。如果是前后端分离的项目,会在前期约定接口,进行基于契约的并行开发。所以,我们称这种方式为数据驱动开发,或基于数据模型的开发。

什么是领域驱动设计?


   《领域驱动设计 软件核心复杂性应对之道》这本书是由 Eric Evans “领域驱动设计之父”,世界杰出软件建模专家所写。市面上绝大多数方法论资料的源头都是出自作者。建议大家买来纸质书或电子书看看。

     正如这本书的副标题所说,领域驱动设计就是为了解决软件的核心复杂性的。


回首过去


      在我以前的软件开发经验中,很多软件都是基于分层思想+贫血模式设计的(如下图)。我从入行就开始学习在MVC模式下进行编码开发。各种框架如strtus、mybatis、hibernate springMVC的应用也都基于此模式来进行。

    在多年的开发过程中,经历过

  •      用mybatis替换hibernate
  •      用springMVC替换struts
  •      业务逻辑重重的写在service层,因为太重又进行了多次重构


30.png


 再回顾下我们的研发流程:一般是从需求开始,产品同学将需求分析完和开发同学进行需求评审,评审完毕后开发同学开始基于需求进行设计,一般会落到数据库设计,将库表设计完毕后,再向上进行分层开发。如果是前后端分离的项目,会在前期约定接口,进行基于契约的并行开发。所以,我们称这种方式为数据驱动开发,或基于数据模型的开发。


31.png


image.png


聊聊现在


      时代在发展,当年一个单体应用就是一个项目和软件,现在一个个的单体都被消灭了,大家也都转向了分布式和微服务。各种拆分、解耦,微服务大行其道,让计算机软件能够承载更多的需求,解决更大的问题。然而有利也有弊,比如:就算单体应用再大,对于一个新人而言,一个业务逻辑debug一趟也基本了解了。而在微服务架构下,一个服务的调用链可能连开发者自己都不一定能梳理清楚(一般要借助工具)。想把所有的逻辑完整的弄清楚是件很困难的事,系统越大越复杂越困难。即便在服务边界内由于代码并没有很清晰的业务概念和描述,也很难快速理解业务逻辑。你可能说这是新人,等新人成长了就好了。(呵呵,新人的体验差真的不解决一下吗?)老人就没有问题吗?当业务逻辑越来越复杂,代码越来越腐败,文档没人维护,留给你的也基本算是一滩沼泽了。我有过这种经历,那种想重新写个新服务的想法特别强烈。


      总结来说,我们在新时代拥抱了微服务和分布式解决了很多扩展性上的问题,然后并没有解决软件复杂性的问题,具体来说有:


  • 代码没体现业务,光看代码不能支撑你理解业务
  • 业务知识没有沉淀下来,对于业务的理解只能找业务专家和技术老人拼图(产品文档更新不及时,最终还是要看代码)
  • 软件工程师沦为CURD工程师 (何时能走上业务专家的路?)
  • 系统逐渐走向复杂和庞大,对系统的修改由于太过复杂和不甚了解而变得战战兢兢。
  • 代码腐败,扩展性差、迭代困难(从立项到重写)


展望未来


      幸运的是,我们并不是第一个遇到这种问题的人,在经历了大量类似场景后,前人们归纳总结了解决问题的办法,更幸运的是它与我们流行的微服务、分布式理论又是那么的契合。这就是领域驱动设计。


33.png


34.png


观察上图,战略和战术设计是站在DDD的角度进行划分。战略设计侧重于高层次、宏观上去划分和集成限界上下文,而战术设计则关注更具体使用建模工具来细化上下文。


      DDD战略设计产生的领域模型可以作为微服务设计的输入。此时,DDD的战术设计又恰好可以与微服务的设计完美无缝结合。

 

(上面这两段话懂的就懂了,不懂的,我们在后文还会再继续阐述,结合前面的知识你一定能明白。)


统一的语言


     这是领域驱动设计的第一步,也是非常重要的一步,好的开始是成功的一半。


    开发团队与领域专家针对具体问题域与业务期望进行沟通,那么沟通要有统一的语言,不然产品有产品的术语,技术有技术的术语,业务还有业务的术语,大家鸡同鸭讲如何能把事儿说清楚?当然主要还是要依赖于业务,将业务术语和逻辑搞明白了,大家有统一而清晰的认识。(刚开始可能不明白,需要多与业务沟通,了解清楚,从源头就搞错了就尴尬了)。


    这是一个将业务领域知识转化的过程,这里最熟悉业务的当然是领域专业或者业务专家,然而我们不是完全把他们所说的原封不动地copy下来,我们是要基于这些业务,用我们的技术知识、产品知识做出可用的软件来,最终它是个软件,我们把这些知识结合在一起,产出一个既满足业务逻辑又是合理的模型抽象。所有甚至有时候技术人员要让领域专家理解技术的解决方法。这样进行反复的沟通才能最终生出好的领域模型。这是建模的过程。


      有了统一的认识如何落地?具体来说就是我们要落到纸面上,以便所有相关人员的理解,后面的开发、沟通都要基于这个。一般我们会用画图的方式,当然也可以结合一些文档说明。这就是统一的语言,将模型用统一的语言(图、文档)描述出来。所有人对业务的理解都是一致统一的。

模型,这种知识形式对知识进行了选择性的简化和有意的结构化。适当的模型可以使人理解信息的意义,并专注于问题


    那有没有可用的工具和方法?还真有。(domain story telling )

    方法:domain story telling

    网站:https://domainstorytelling.org/

    建模工具:https://github.com/WPS/domain-story-modeler

   

最终画出的图类似这样:


35.png


    domain story telling 只有四类元素来表达领域模型


36.png


  •   actor’s             演员,可以是人、团体或软件系统
  •       work objects     操作的对象,比如文档、消息等
  •       activities          动作
  •       annotations      注释


     利用统一的语言最终产出的就是最初的领域概念模型(后面实践篇,我们会看些具体例子)


  接下来我们会对这个模型进行领域分析和考虑划分领域,找到领域边界。


image.png


未完待续......


相关文章
|
7月前
|
领域建模
架构设计 DDD领域建模 核心概念
【1月更文挑战第6天】架构设计 DDD领域建模 核心概念
|
设计模式 缓存 自然语言处理
DDD领域驱动设计如何进行工程化落地
DDD领域驱动设计到底如何进行实际的工程化落地,为什么要进行领域分层?本文主要围绕DDD领域分层,设计了可落地的工程结构。
DDD领域驱动设计如何进行工程化落地
|
存储 自然语言处理 前端开发
领域驱动设计(DDD)-基础思想
一、序言     领域驱动设计是一种解决业务复杂性的设计思想,不是一种标准规则的解决方法。在领域驱动设计理念上,各路大侠的观点也是各有不同,能力有限、欢迎留言讨论。 二、领域驱动设计 DDD是什么 wiki释义:     领域驱动设计(英语:Domain-driven design,缩写 DDD)是一种通过将实现连接到持续进化的模型[1]来满足复杂
7550 0
|
Cloud Native 架构师 Devops
云原生时代领域驱动设计(DDD)的价值——从《没有银弹》说起
软件开发需要面对本质困难和附属困难。云原生、DevOps实践大幅降低了附属困难,使得架构师可以全力聚焦于业务复杂性,而DDD恰是管理业务复杂性的有效方法。
1592 0
云原生时代领域驱动设计(DDD)的价值——从《没有银弹》说起
|
4月前
|
缓存 架构师 中间件
成为工程师 - 如何做DDD领域驱动设计?
成为工程师 - 如何做DDD领域驱动设计?
|
前端开发 架构师 Java
领域驱动设计DDD从入门到代码实践
在本文中,作者将借鉴《实现领域驱动设计》的做法,介绍领域驱动设计的基本概念的同时,用一个虚拟的公司和一个虚拟的项目,把领域驱动设计进行落地实践。
13474 9
领域驱动设计DDD从入门到代码实践
|
存储 设计模式 前端开发
浅谈领域驱动设计实践——董炎焱
近年来领域驱动设计(Domain Drive Design)大火。那么我们为什么要学习领域驱动设计,它适合用于哪些场景?怎么去用?在用的过程中,又有哪些需要注意的地方呢?
浅谈领域驱动设计实践——董炎焱
|
领域建模 数据库
领域驱动设计总结——简介
本文为领域驱动设计系列总结的开篇,主要对领域驱动设计概念做个介绍,本系列领域驱动设计总结主要是在Eric Evans 所编写的《领域驱动设计》 一书的基础上进行归纳和总结。
157 0
|
存储 消息中间件 JSON
领域驱动设计:从理论到实践,一文带你掌握DDD!
学习DDD一个半月,最开始学习DDD的原因是因为我负责的业务线,涉及的系统非常多,想借鉴领域驱动设计的思想,看后续如何对系统进行重构。在没有学习DDD之前,感觉DDD可能属于那种“虚头巴脑”的东西,学完DDD之后,感觉。。。嗯。。。真香!
1800 0
领域驱动设计:从理论到实践,一文带你掌握DDD!