“领域驱动设计”答疑(二)

model

问题:我们当前为了安全性在做的一些软件的形式化建模工作,算是领域建模不?

这个问题可以和下面几个问题一起回答:

  • “领域模型和我们的设计文档里的架构设计图有啥区别?”

  • “领域建模最核心的是不是就是做好数据建模?”

  • “模型驱动架构(MDA:Model-Driven Architecture)算是领域驱动开发吗?”

先说答案:统统不是领域建模!


补充一下:上面的回答是站在狭义的角度说的。

让我们先从更广的角度讨论一下软件建模这件事。

建模是一个软件设计活动,而软件设计是为了长期低成本的实现需求。所以建模服务于两个目标:即让软件满足需求长期低成本

软件工程到今天,正确性(即满足需求)的主要保证手段依然是测试!

还有另一种保证程序正确性的手段是“证明”,遗憾的是用“证明”保证程序正确性这件事到今天在工程化上仍然不是很成熟,有以下的限制。

首先,程序的编写要满足一定的约束(例如状态不可变)或满足某种数学形式化要求(例如必须抽象为有限状态机集合)。这让模型离业务域过远,增加了编程的门槛,同时增加了程序的理解难度和维护难度。

其次,程序的证明也是run在计算机上的,需要耗费大量的计算资源和时间,因此对于被证明程序的规模有要求,太大的程序难以在接受的时间内得到结果。为了效率经常会将完整证明退化为只证明程序不会破坏某些约束或者不变式。

最后,要认识到,即使是经过完整证明的程序也不能保证在现实环境中百分百的可靠。程序在和复杂的外部世界打交道的过程中,不可避免会有“意料之外”的情况传递到软件内部,让软件表现的不符合预期。这种“意料之外”是没有办法提前完全预测的,正确性的边际成本只会越来越高。现实的做法是为不同部分的软件设定不同的承诺指标,然后采用不同的手段满足不同的承诺,从而让整体的成本最低。

目前采用形式化验证的软件,集中在对安全性要求高、 被验证部分的软件规模有限、且需求又相对稳定的领域,比如航空、驾驶、医疗、通讯基础设施等领域。而绝大部分在意成本又经常修改的软件,依然是采用测试来保证软件满足规划的所有需求场景。

让我们再回到软件设计的另一个目标,即“长期低成本”!

软件成本主要由两个方面组成:可理解性和可复用性。可理解性和可复用度高的软件,变更和验证的成本都会低很多。

因此,我们可以将软件建模的目标大致的归结为以下三个:

  • 让软件更容易验证其正确性
  • 让软件更容易被理解
  • 让软件的可复用度尽可能高。

遗憾的是,这几个目标有的时候可能会有冲突。例如,形式化建模可以让软件自动化的被验证,但是它需要将软件建模为某种偏数学的形式化模型,于是软件实现就会离业务的距离更远,降低了软件的可理解性。再比如为了让软件的可复用度尽可能的高,会为软件增加非常多的抽象层,也会降低软件的可理解性。

所以不同类型的软件需要根据自己的特点,找到自己可接受的平衡点。

而不同建模方法,瞄准的目标也是不同的,软件需要根据自己的平衡点,选择和使用不同的建模方法。

如前文所叙,“形式化建模”主要瞄准的是软件的正确性。

再来看“数据建模”。它是从数据的角度设计程序,通过分析和抽象软件中关注的数据概念、关系和完整性,并将其映射到对应的数据存储模型上。数据建模关注的是软件的数据组织方式能否正确的完成功能,以能否正确高效的映射到存储模型上。数据建模有助于程序的正确性以及可理解性。

遗憾的是“数据建模”没有关注行为和数据之间的关系。而程序的“可复用度”要高的话,则需要按照高内聚、低耦合的方式组织程序,让行为和紧密相关的数据在一起,对外隐藏数据,复用行为。这就是“面向对象建模”做的事。它不仅考虑数据概念、还关注行为概念以及它们之间的关系。面向对象建模不仅能提升软件的可理解性,还能提升软件的可复用性。

而MDA(Model Driven Architecture)如之前的文章所述,试图通过UML将面向对象建模标准化,使得模型可以脱离具体的实现技术被复用,以及提高模型到代码之间的转化效率。

还有另外一个和MDA属于亲戚关系的系统设计方法,就是INCOSE(International Councilon Systems Engineering: 系统工程国际委员会) 提出的 MBSE(Model-Based Systems Engineering: 基于模型的系统工程)。

MBSE是INCOSE觉得OMG(Object ManagementGroup) 搞的UML和MDA对于系统工程来说不够严谨,于是自己搞了一套系统工程方法论。MBSE包含建模语言,建模工具和建模方法等一系列相对完备的方法和过程,在整个流程中要求以严谨的模型驱动设计过程。

MBSE的建模语言为SysML,它是基于UML2.0上做了增减,主要是增加了更适合系统需求工程的需求图以及可用于性能分析和定量分析的参数图。目前该方法主要用于对安全、性能要求比较高的软硬件结合类产品中,例如汽车工业以及其它实时嵌入式软硬件产品等。

MBSE的建模流程是比较厚重的,多个阶段模型按照阶段转化求精,对于交付节奏快的软件产品有些笨重。另外MBSE中的模型主要是面向系统设计和前期验证,并不侧重于直接指导代码开发。

最后我们来看领域驱动设计里的“领域建模”。领域建模的目标是用于在限定范围内建立一个业务专家和开发团队能达成共识的软件模型,用于指导软件实现并保持概念一致性,降低沟通成本。领域建模是在软件可理解性和可复用性中间找到一条工程和技术上可行的平衡点。

如我们之前的文章所书,领域驱动设计给领域建模提了目标,给了若干建议,但是并没有限定采用哪种具体的建模技术,只要能达到它所设立的目标就行。这给了它极大的扩展空间,也正因如此这门技术现如今被社区发展得似乎“无所不包”。

不过通过前文分析,我们还是能看到“形式化建模”、“数据建模”、“面向对象建模”和“MDA”瞄准的目标和领域建模的目标都不尽相同,所以从狭义的角度说,上述建模都不是领域建模。

但是远近亲疏毕竟还是有所不同,领域建模更多的还是会采用面向对象建模,是因为相比之下面向对象建模更成熟和系统,更能接近领域驱动设计所追求的目标。

不过,领域驱动设计强调在软件分析、设计和实现阶段只存在一个模型,这个模型要能桥接业务专家和软件开发团队,联通问题域与解决方案域。因此“领域模型”更偏向于面向对象中的“分析模型”与“设计模型”的融合模型

我在工作实践中应用领域驱动设计,是因为它提倡建模工作以领域为核心,以在代码中落地为目标,能够兼顾业务和实现。具体到建模方法上虽然以面向对象建模方法为核心,但也会经常借鉴或使用其它方法。毕竟好的设计是一种平衡,任何方法都是工具!

最后,以模型作为分析设计工具,驱动软件开发的方法,有个统称叫做“模型驱动开发”(MDD Model-Driven Development,注意,不是MDA)。面向对象建模,MDA,领域建模都可以认为是模型驱动开发。许多形式化方法支持以图形化或者DSL(领域特定语言)的方式建模,也支持代码自动生成,号称自己是模型驱动开发,是没错的。

还漏了一个问题:“领域模型和我们设计文档里的架构设计图有啥区别?”

答:如果你们设计文档里面的架构图是业务专家和软件开发者之间的关于软件如何解决业务问题的模型共识,并且和代码保持一致,那么就是领域模型。如果仅是为了演示、或者划分软件功能模块、定责任田,那很抱歉,不是领域模型。


《“领域驱动设计”答疑(三)》

《“领域驱动设计”答疑(汇总)》

你可能感兴趣的:(“领域驱动设计”答疑(二))