领域驱动设计的优点和挑战

这是来自drdobbs的Dino Esposito文章。在领域驱动设计提出后这十年,DDD已经证明对于某些复杂项目是有效的,为实践提供了适当的指导。

大约十年前,Eric Evans提出新的软件开发方法:领域驱动设计(DDD),这是一本很受欢迎的书籍。

起初,DDD听起来像一个相当有前途的方法。对于一个复杂的项目开发人员来说非常诱人。在DDD中,一旦理解了软件需要解决的业务领域,那么你所要做的就是建立一个分层架构,业务逻辑被分成两个不同的模块,核心域逻辑(相对用例是不变的)和应用程序逻辑(用例)的实现。

DDD有其自身的分析部件(如通用语言,有界的上下文和上下文映射;它有一个战略组成部分方面用来严格支持相关软件架构和实现。流行的富领域模型(充血模型)只是许多可能的支持架构的其中之一。(一个基于充血领域模型的系统本质上并不比一个普通的CRUD系统更好,只要这两个系统满足需求。软件的复杂性主要源于基础业务的复杂性问题)。

DDD为理解错综复杂的业务领域提供了宝贵帮助。DDD提供的分析部分要好于其支持架构。DDD无处不在的语言提供一个方法来了解关键术语:名词、动词、副词——这些都是由业务专家使用。通过建立这样一个词汇,架构师和开发人员也可以理解它们。因为即使在同一家公司,语言会经常变化,使用相同的术语却意味着不同的东西或代表不同的聚合数据,这就造成沟通混乱。这种情况下形成一个最终系统的有界上下文,就像一个黑盒连接到系统的其余部分。上下文映射是连接上下文的映射图。每个环境都有自己的语言,使用一个独立的实现和接口与其他有界的上下文交互调用。整个系统就是由有界的上下文组成。DDD的最终目的是在有界的上下文中实现清晰而明确的收集需求。

DDD应对软件设计的复杂性不是作弊,。它将专注于问题域。然而,DDD却是很容易被做错,从而带来显著的成本。

普遍认为,虽然可以使用DDD带来明显的好处,但是却难以解释为什么需要实现这些好处。事实是,在过去的十年中,许多项目使用DDD有许多成功与失败。那些最终成功仍然经历了相当多的困难。为什么?

我的理解是,对DDD有一些误解,最重要的是,DDD往往减少到仅仅是建设项目中的一个领域模型。但也有一些其他的误解,比如将领域模型看成需要包含所有可能的行动,还有,将领域模型的构件(如通用语言)作为直接实现细节(抽象和具象不分)。

我叫他们为“误解”——从字面上,基于错误的观点或意见不正确的思考和理解。根据起点和上下文每个感知都可以是正确或错误。DDD的起点是它为设计服务的,然后才可能为落地实现细节的目的服务。所以,事实上,实现细节在哪里?

DDD有助于发现高层架构,发现软件需要复制的领域中的机制和动态。具体地说,它意味着一个好DDD分析会最小化减轻领域专家和软件架构师之间的误解,并且减少了后续昂贵的需求变化的数量。

通过分割复杂性领域到较小的上下文场景,DDD避免让项目架构师设计一个臃肿的对象模型,这个胖模型花费大量的无用时间在工作实现细节——部分原因是实体处理通常数量的增长超出了大小会议室的白板。(因为细节太多,超过会议讨论的范围,具体实现时会加入到对象模型中造成臃肿庞大的一个大对象,DDD目标是在会议讨论时将这些细节提前设计切分为上下文场景)

DDD针对特定类型的项目是一种有效的技术:复杂的项目通常有一个很大的问题域,需要与领域专家交流需求。使用一个模型直接落地为一个编程设计(一般来说,OO)实现,对于这些项目,这几乎是理想状态。然而。理解领域模型如何准确地映射到编程实现是至关重要的,这一步往往决定了项目的成败。


2014-10-09 10:43 "@banq"的内容
理解领域模型如何准确地映射到编程实现是至关重要的,这一步往往决定了项目的成败 ...

呵呵,最近闲来无事,又来捧场。
这个帖子,一个让我思考的点,居然是‘副词’。。。
另外一个点,这个帖子说明了,领域分析专家,再也无法轻松的说只专注于分析问题域了,因为他分析设计出来的东东,很可能无法落地,哈哈,那就什么也不是了。。。看起来像废话,不过好在本着‘实践’的精神,那些指导方针都还是考虑了如何成功降落的问题

2014-10-09 23:05 "@ericyang"的内容
这个帖子说明了,领域分析专家,再也无法轻松的说只专注于分析问题域了,因为他分析设计出来的东东,很可能无法落地 ...

领域分析专家有时是产品经理,对于一个复杂项目,如何让产品经理和架构师(技术负责人)统一交流语言,DDD提供了一种简单有效的方法,当产品经理说某个领域模型 在什么上下文发生什么事件动作时,技术人员应该明白那是怎么回事,如何实现。

该文一种观点认为贫血模型和充血模型在实现需求时区别不大,我个人不是很认同,贫血模型很显然走到臃肿模型的另外一个极端:

贫血模型(类似纯粹数据结构) -->充血模型 ---->臃肿模型

因为贫血模型的将一些业务职责割裂出去,比如放到服务之中,那么当维护拓展时,我们可能去修改服务,而服务应该是客户直接调用的接口,是连接前后端的节点,如果这个节点发生修改,会影响客户端代码,这是相当危险的。

其实虽然我们的业务逻辑有些变更,但是对客户服务接口可以不变,比如加油站的油价提高了,加油服务不会变,客户来了还是享受和以前一样的加油服务,将车开到加油机,指定油号加油。

后端系统中就简单两个模型:服务和实体,其实学问大了,通常Spring/JavaEE是将实体作为贫血模型使用,大量逻辑在服务中,服务的每个方法都很臃肿,这就是CRUD系统的现状。

显著的优点是减少沟通成本,发现潜在需求,挑战方面,要象设计架构一样来设计领域逻辑,需要抽象、抽象、再抽象

2014-10-11 08:06 "@banq"的内容
领域分析专家有时是产品经理 ...

所以有个兄弟说DDD难,必须要有丰富的程序开发,设计,架构经验,丰富的质量管理经验,丰富的产品管理经验,丰富的需求分析和客户沟通经验,当然,少不了还得是一个成功的项目经理人,,有点像几十年前对系统分析师的资格要求。比如,通用语言这一关,很多项目就铩羽在这一块。今早还碰到一例,我一个需求分析师和客户就是牛头不对马嘴的在谈变更,特别跨国项目,这个问题的影响就更显著了。

问各位一下:什么才是真正“复杂”的系统?
过去几年还没有真正碰见所谓的负载的系统,我的关注是数据,数据的产生、数据的流向、数据的存储,数据的提取。搞定这几个过程,就能实现对应的商业价值。

2014-10-12 11:11 "@hanyh2004"的内容
我的关注是数据 ...

你是唯数据论啊,现在大数据盛行,加油啊。。。
从你的偏好和认识上,感觉你是个数据分析师哦,要不做BI的?ETL?还是数据仓库?
不过,你讲得太笼统,很难说服你,所以去baidu了下,帖在下面,抛砖引玉,坐等别人,呵呵:
复杂系统是具有中等数目基于局部信息做出行动的智能性、自适应性主体的系统。复杂系统是相对牛顿时代以来构成科学事业焦点的简单系统相比而言的,具有根本性的不同。简单系统它们之间的相互作用比较弱,比如封闭的气体或遥远的星系,以至于我们能够应用简单的统计平均的方法来研究它们的行为。而复杂并不一定与系统的规模成正比,复杂系统要有一定的规模,复杂系统中的个体一般来讲具有一定的智能性,例如组织中的细胞、股市中的股民、城市交通系统中的司机,这些个体都可以根据自身所处的部分环境通过自己的规则进行智能的判断或决策。

2014-10-12 11:11 "@hanyh2004"的内容
什么才是真正“复杂”的系统 ...

复杂这个概念也有些因人而异,关键是找到将复杂简单化的好方法,你从数据角度也许是适合你的一个好方法,而如果能理解DDD,可能也是一种快速完成复杂系统的方法,打个比喻:高手之间一个眼神就已经知道对方的意思,低手需要巴拉巴拉半天还是没搞明白。

参考另外一种low-code快速开发平台案例:
http://www.jdon.com/46756

DDD提供了一种简单有效的方法,当产品经理说某个领域模型 在什么上下文发生什么事件动作时,技术人员应该明白那是怎么回事,如何实现。

=======================

其实软件归根还是实现人与人的交互,不管是软件使用过程还是实现过程。

不懂的人不能用。需求设计要考虑实现,只考虑需求的,实现起来估计会有很大问题。

比如加油站的油价提高了,加油服务不会变,客户来了还是享受和以前一样的加油服务,将车开到加油机,指定油号加油。

简单明白


[该贴被m3310于2015-03-31 10:03修改过]

2015-03-31 09:59 "@m3310"的内容
比如加油站的油价提高了,加油服务不会变,客户来了还是享受和以前一样的加油服务,将车开到加油机,指定油号加油。 ...

加油站是怎样一个系统?给它输入钱,它会往外输出油。加油站中的油经管道被cpu驱动压入外部的车子系统中去了。这个过程是时空变换的过程。钱进系统了,油从系统中出来了,原来3快钱能出来1升油,现在3快钱只出来半升油,现在的时空变换和以前的时空变换是有差别的,但是这种差别比较小,明显的感受到的只是量变,只是现在买来的油比以前少了一半。两边还没能达成质变,车子和加油站共同构造的那个时空布局依然稳定,但是如果量变累积到3块钱只能买一滴油的程度的话很可能会发生质变,车子和加油站共同营造的那个时空布局很可能土崩瓦解,人们可能会拆除加油站、更换燃料、不旅行了等这样的措施,既改变外部的客体又改变内部的主体。
我最近发觉这种分析的方法能够调动我们的右脑,非常的直观,发觉整个计算机世界跟我们的现实世界一直都是同一个世界,一直都是同样的运作方式。计算机世界之所以那么难弄,很可能是因为计算机的空间体积比我们小,我们钻不进去,如果能分神钻进去的话这样可以帮助激活右脑。如果宇宙真有一个极限速度的话,感觉计算机之所以能够为我们赢得时间可能正是因为它的空间很小的缘故。