Skip to the content.

引言

消化知识

这部分的重点是,面对自己陌生的领域,需要为这个领域开发一款软件,该如何学习、面对这个领域内庞大的知识。

交流与语言的使用

你是一名软件工程师,他是一名硬件工程师,现在要设计一个类似于PCB的软件,两者的知识体系相差这么大,如何交流?

设计一种通用的语言,用该种语言进行交流。

交流的过程中由于双方的知识体系不同,同一个术语其含义可能相差甚远,如何解决这种差异。定义通用的交流方式进行交流。

举例

多数的软件开发过程运用的都是贫血模型,把他当作面向过程来操作的。贫血模型开发方便,对开发人员的要求低。如 JavaEE 开发,开发人员熟悉三层架构后便可进行开发。主流的开发框架 Spring、Hibernate 等都鼓励使用贫血模型,因为理解了三层架构后,上手编码很快。

三层架构

我们倾向于把业务放在 Service 中。对于简单的项目用贫血模型是可以的,但是对于大型的软件架构这种方式是不合适的。

一种解决办法是,采用领域模型,即运用设计模式。

软件开发不是一蹴而就的事情,我们不可能在不了解产品(或行业领域)的前提下进行软件开发,在开发前需要进行大量的业务知识梳理,而后到达软件设计的层面,最后才是开发。在梳理业务的过程中,我们必然会形成某个领域知识,根据领域知识来一步一步驱动软件设计。领域驱动设计的核心就在于建立正确的领域驱动模型!

graph LR
业务知识梳理==>软件设计==>开发

正如书名:领域驱动设计,应对软件复杂性之道。

问题假设

假设某公司出售三种产品:文字处理软件、数据库、电子表格。其中:

贫血模型

先来表设计,再利用三层架构,写代码。

为什么叫贫血模型?

优点:

缺点:

贫血模型对于业务逻辑不复杂的项目来说是值得选择的,不能完全排斥。

领域驱动模型

DDD:DDD 是一种以领域为核心的设计和开发理念。DDD 通过维护一个深度反应领域概念的模型,以及提供了可行的经过实践检验的大量模式来应对领域的复杂性。

领域模型

领域与业务密切相关,不同领域涉及的业务差别很大。业务是学习不完的,故采用领域的方式抽象出模型。领域与业务之间需要交流,人员之间的交流存在障碍,需要突破这层障碍。【现在的感觉是,外科医生式团队。高层人员交流,设计出领域模型,普通开发人员根据领域模型进行开发,减少开发成本。】

通用语言

需要领域专家参与,仅靠用户文档是无法很好完成的~

我们需要一种通用的语言,让团队在交流时能达到一致。

特点

领域驱动开发一开始并不考虑数据库表,先找业务领域中那些东西可以成为领域对象,领域实体。

业务简单的话,贫血模型更具优势~

空中交通监控项目

开发人员:我们想监考空中交通,应该从哪里开始?

专家:让我们从最基础的开始吧。所有交通由飞机组成。每架飞机从一个出发点起飞,并在一个目的地点着陆。

graph RL
Destination==>Aircraft===Departure

开发人员:飞行时,飞行员按照驾驶员的意愿选择任何空中路线吗?

专家:不,驾驶员需要按照他们收到的规定路径行驶。

graph LR
Aircraft==>Route==>Departure
Route==>Destination

开发人员:飞机是直线飞行吗?

专家:不是直线飞行,你可以想象成是一系列的线段组成的。每个线段的两端都是方位,所以模型应该这样:

graph LR
Aircraft===Route==*==>Fix

开发人员:这样一来,出发地和目的地也包含在一个个方位中了。

专家:是的。

开发人员:把路线考虑成空中的3D线路。如果我们使用笛卡尔系统坐标,那么一条飞行路线会被简化成一系列的3D的点。

专家:笛卡尔??

开发人员:。。。。

graph LR
Aircraft===Route==*==>Fix==>3DPoint

专家:实际上我们不会这样看待飞行路线。飞行路线是飞机预期的空中线路在地面上的映射。飞行路线会穿过一系列地面上的点,而这些点我们可以用经度和纬度来决定。

开发人员:哦,都是地球表面的点?我们用一些列2D的点来描述线路。

graph LR
Aircraft===Route==*==>Fix==>2DPoint

开发人员:飞机的飞行高度是否可以自行选择?

专家:不行。飞机在一个特定的海拔高度,会在飞行计划中有规定

开发人员:飞行计划?新名词?

专家:在离开机场之前,驾驶员会接到一个详细的飞行计划,包括所有关于此次飞行的信息:飞行路线,巡航高度、巡航速度和飞机的类型,甚至是机组成员的信息。

开发人员:飞行计划相当重要~

graph LR
Aircraf==>Flight.Plan==>Route==>Fix==>2DPoint

领域模型就建立起来了~

先建立通用语言,画出通用图,双方讨论,理解对方的意思。

DDD分层架构

分层结构

说明
用户界面/展现层 负责向用户展现信息以及解释用户命令
应用层 很薄的一层,用来协调应用的活动。不包含业务逻辑。不保留业务对象的状态,但它保有应用任务的进度状态。
领域层 包含关于领域的信息。是业务软件的核心所在,在这里保留业务对象的状态,对业务对象和它们状态的持久化被委托给了基础设施层。
基础设施层 本层作为其他层的支撑库存在。它提供了层间的通信,实现对业务对象的持久化,包含对用户界面层的支撑库等作用。

贫血模型是各种领域的操作可能集中在一个 servcie 中进行。充血模型是每个领域只关注自己的事。把原来 service 中的逻辑移到领域中去了,不过领域要设计好才行~

领域层有什么

运用领域模型

开篇

开篇主要是普及一些概念,并举例进行说明,便于读者理解。

领域驱动设计的三个基本用途

软件的核心

下面的话,好真实,引起不适。

故事环节

技术人员在意技术,可拓展性;用户在意便利性,两者之间可能存在某种冲突。

​ 一部电影中的精彩片段,差点因为一个剪辑师的“专业性”而被删除。这中导演和剪辑师专业性的差异,在现代的软件开发中或许是很常见的。技术人员在意的是技术上的问题,如何更加高效,拓展性更强,而用户在意的确实使用方式和是否便利。这种差异性让开发人员和用户直接的矛盾显得特别的突出。我们要理解领域模型,理解领域核心的领导者可以将项目带回到正确的轨道上。

开发人员可以采用一些系统性的思考方法来透彻地理解领域并开发出有效的模型

消化知识

交流,抓住重点,设计或使用一种通用的描述语言进行交流。【理解方面也会存在偏差吧。】

问题

不同技术人员的专业技能上的差异,带来交流上的困难。

几年前,我着手设计一个用于设计印制电路板(PCB)的专用软件工具。但有一个问题,我对电子硬件一无所知。当然,我也曾拜访过一些PCB设计师,但用不了3分钟,他们就令我晕头转向。如何才能了解足够多的知识,以便开始编写这个软件呢?当然,我并不打算在交付期限到来之前成为电子工程师。

他们可能是个硬件高手,但是对软件他们的知识可能很匮乏。

解决过程

有效建模的要素