---
title: "领域驱动设计：从学习到实践（一）"
description: "什么是领域驱动设计？"
date: 2020-07-16T10:08:09Z
canonical: https://xiaobox.github.io/p/2020-07-16-ling-yu-qu-dong-she-ji-cong-xue-xi-dao-shi-jian-yi/
author: 小盒子
categories: ["架构与方法"]
tags: ["微服务", "架构"]
source: https://mp.weixin.qq.com/s/PHfx3MWXs1nDNy_BI7XGrw
license: CC BY-NC-SA 4.0
license_url: https://creativecommons.org/licenses/by-nc-sa/4.0/
---

# 领域驱动设计：从学习到实践（一）

![Image](https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2020-07-16-ling-yu-qu-dong-she-ji-cong-xue-xi-dao-shi-jian-yi/001-512a70cd.png)

###

###

###

### 什么是领域驱动设计？

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

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

### 回首过去

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

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

-         用mybatis替换hibernate

-         用springMVC替换struts

-         业务逻辑重重的写在service层，因为太重又进行了多次重构

![Image](002-a3f3c4dd.png "image.png")

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

                              **![Image](003-2e8f3777.png "image.png")              ![Image](004-94d15702.png "image.png")**

### 聊聊现在

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

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

-   代码没体现业务，光看代码不能支撑你理解业务

-   业务知识没有沉淀下来，对于业务的理解只能找业务专家和技术老人拼图（产品文档更新不及时，最终还是要看代码）

-   软件工程师沦为CURD工程师 （何时能走上业务专家的路？）

-   系统逐渐走向复杂和庞大，对系统的修改由于太过复杂和不甚了解而变得战战兢兢。

-   代码腐败，扩展性差、迭代困难（从立项到重写）

### 展望未来

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

**![Image](005-0d82379f.png "image.png")![Image](006-2564870d.png "image.png")**

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

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

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

### 统一的语言

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

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

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

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

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

     那有没有可用的工具和方法？还真有。（domain story telling ）

     方法：domain story telling

     网站：https://domainstorytelling.org/

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

 **最终画出的图类似这样：![Image](007-6296f1d4.png "image.png")**

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

     **![Image](008-a4951963.png "image.png")**

-          **actor’s             演员，可以是人、团体或软件系统**

-          **work objects     操作的对象，比如文档、消息等**

-          **activities          动作**

-          **annotations      注释**

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

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

![Image](009-2127ded0.png "image.png")

未完待续......

![Image](https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2020-07-16-ling-yu-qu-dong-she-ji-cong-xue-xi-dao-shi-jian-yi/010-84e813ce.jpg)

关注公众号 获取更多精彩内容

