“领域驱动设计”(以下简称“DDD”)号称“OO done right", 也就是”面向对象方法学的正确实施方式“。自2003年提出以来,虽然在一些软件开发专家的圈子里得到盛赞,然而真实的企业级应用中却是曲高和寡。十几年过去了,这两年DDD却又重新成了软件开发方法学的热点。当和朋友们聊起这一有趣的现象时,常常会碰到以下几个问题:
1. 既然有了面向对象方法学,为什么还需要DDD?
2. DDD既然得到这么多专家的称赞,为什么自从2003年出现以来一直没有真正流行起来?
3. DDD在这两年为什么又成了热点?
4. DDD的未来会是怎样的?
一切都要从布鲁斯老爷子的人月神话说起。书中有两个互相关联的观点,和本文的观点有关。一是书中认为把业务知识搞清,是最困难的,而不是如何把这些知识表达出来。二是有关软件的本质困难和非本质困难。软件的本质困难指的是软件本身的复杂性。非本质困难,指的是具体的工具和技术。非本职复杂性是可以通过技术的改进本身逐渐消除的。本质复杂性是无法消除的,只能控制。综合起来,我们可以认为,业务领域本身的复杂性,是软件本职复杂性的重要组成部分。几十年来,软件开发。方法学的发展,可以说,就是逐渐控制软件的本质复杂性。如何应对软件的本质复杂性,以及如何消除非本质复杂性的过程。下面重点谈一下,如何,管理和控制业务领域本身的复杂性。
这里所说的管理指的是,使一件复杂的事情,变得可以控制和预测和可行,而不致因为失控而导致失败。
首先人们在60年代提出了软件工程。软件工程早期的重要成果是结构化软件开发方法学。在套体系下,我们是怎样对领域进行建模的呢?人们用数据流图,来建模行为以及信息变化的关系。另一方面,利用实体联系图建模数据库。这种方法最大的问题在于,以上两种方法没有进行有效的联系。也就是说,从动态和静态两方面去分析业务领域本身没有问题,问题在于两者之间没有有机的联系,没有达成一致,这种内在的不一致性造成开发的困难。这一方法学另外一个问题在于,没有一个自然的方法,从分析过渡到设计。以下是一个例子。
当人们逐渐意识到这些问题的时候,面向对象的方法就应运而生了。通过对象,将,静态的属性和动态的行为,结合起来。仅从静态的角度来看,面向对象的建模,比实体联系图更强大,更有表现力,更容易深挖,领域知识。其动态的一面,借由,顺序图,用力等方法。将动静结合起来。此外,面向对象的分析设计采用同样的表达方法。面向对象的设计结果,又可以自然的,演化成数据库和程序。面向对象语言写的程序。从而系统地解决了,结构化方法中的相应的缺失。以下是一个例子。
到90年代中期,自由uml产生以来,面向对象走向了一个巅峰。在某些领域取得了辉煌的成功。比如说编程语言。和图形应用界面。然而在企业应用方面却没有,真正普及。尽管早期,面向对象大师们,索取的例子中,多数都是企业应用的例子.这也就为领域驱动设计的出现埋下了伏笔。在领域驱动设计正式出场,以前,我们先分析一下,面向对象,为什么没有在企业应用中取得成功?主要问题仍然在于业务领域的复杂性。
让我们假想,如果那些面向对象的大师们,来到我们自己的企业,帮我们编写程序。很可能可以成功,但是我们自己做就不行。这说明什么?那些大师心中,必然有一些他们知道而我们不知道的东西。可惜,他们没有把这些内容充分的,系统化,并,整理成书。而领域驱动设计,就把那些大师心中的不传之秘。系统地总结出来,总结出了各种,方法原则和技术。写在书里面,我们一般的人,按图索骥,一葫芦画瓢,也可以应对复杂的,有系统。
也就是说,领域驱动设计系统的解决了,传统面向对象方法的缺失。
由于,业务领域的复杂性。为了构建深刻的准确的领域模型。需要在传统的,面向对象方法基础上,更多的,方法和原则。比如说,领域驱动设计中引入的,聚合。实体,值对象。限界上下文等等。在早期,面向对象大师们,自己的工作中,他们或多或少的,使用了这些思想,但是,没有系统的完整总结下来。直到领域驱动设计。下面举例子。
另一方面,传统软件开发方法,仅仅提供了一套建模方法。而仅仅是,建模方法本身,是不足以分析复杂的领域的。缺乏了协作这一环。领域驱动设计非常强调领域专家和开发人员的协作。这是产生好的领域模型的必要条件。领域驱动设计一再强调这一点,并且提出了统一语言等等方法。明白这一点,我们就知道为什么面向对象方法在编程语言,和图形化用户界面能够取得成功,而在企业应用方面不行了.在编程语言和图形化用户界面的开发方面。可以说开发人员自己就是领域专家。因此不需要和非IT背景的专家协作,就能够把领域搞清楚,哪怕这个领域非常复杂。而在企业应用方面这一点不成立。所以重要的不是模型本身多复杂,而是,如何,与,对的人协作,获得这一模型。
领域驱动设计,提供了层次性的架构。在martin fowler总结了层次型架构之后。
尽管领域驱动设计具有突破性的价值。但是我们一定要注意,领域驱动设计是建立在面向对象的坚实基础之上的,是对面向对象方法的继承和发展。脱离面向对象的方法,是无法成功运用领域驱动设计的。
然而遗憾的是。自从领域驱动设计在2003年产生以来,尽管在小范围内受到了专家们的赞誉。但是,仍然没有真正普及开来。那么问题又出在哪儿呢?
首先,领域驱动设计并没有解决,人月神话所提出的全部本质复杂性问题。
首先如书中所认为的对于复杂的领域,要获得一个。深刻的有效的模型,是不可能一蹴而就的。必须经过,领域专家和IT专家的协作不断演化,才能得到。而领域模型的演化,必然导致程序本身的演化,并且,领域模型的重要的变更将导致软件系统的架构意义上的变革。也就是说,系统必须具有,不断的演进自身架构的能力这一点在传统软件开发中几乎是不可能的,而领域驱动设计本身,并没有,给出有效的解决办法。
另一方面,尽管书中强调了,领域人员和技术人员的充分协作,并提出了一些方法,但是,仍然缺乏全面的,行之有效的,一套系统的方法,达成协作。
此外并没有完全解决软件本身复杂性。透明性和可变性。
软件的不透明性,也要求有一套行之有效的方法,去验证,系统的正确性。顶一驱动设计,同样没有提出,行之有效的方法。
此外,我们也不能不提一下,面向对象技术应用于,企业应用,所走过的长达十几年的一段弯路。
领域驱动设计出版在2003年,在这一年,SUN公司,发表了J2EE1.4。这是J2EE的最后一个版本。而这一,框架的最初版本,则要追溯到1999年底的J2EE1.2.三年后作了重大修正并重新命名为JavaEE5的版本则是后话了。J2EE目的就是企业应用市场。当年J2EE是如此的雄心勃勃。除了微软以外,各大公司,都对其抱以厚望,纷纷追捧。既然IT巨头们都表态了,业界的程序员们当然趋之若鹜。然而J2EE有重大缺陷。其封装领域逻辑的核心机制是EJB。而早期的EJB有两个重大缺陷一是不支持继承,因而无法充分发挥面向对象,建模的威力其编程模式事实上是面向过程。另一方面,这一框架侵入性非常强,技术复杂,从而使程序员,要花很大的精力,研究技术细节本身。那时的程序员,以为花大量时间,掌握了EJB的,技术,就能够顺利的开发,企业应用了。 然而,这正是,大家把大量精力,花在了,人月神话所说的非本质复杂性上,而忽略了真正的,本质复杂性。 这是EJB失败的根本原因。但当时多数人并没有意识到这一点。微软则推出了,DNA与之抗衡。同样要关注技术细节.同样有类似的问题。这一状态被spring框架彻底解决了。然而spring产生的时候,已经没有多少程序员,真的关心面向对象。以面向过程的方式开发企业应用已经成为常态。尽管spring已经具有使人们摆脱技术细节,把精力放在领域模型上的潜力。然而并没有明确的提出来强大的惯性,那是人们在错误的道路上越走越远.大家还记得几年前,市面上大量的ssh的书吧。这些书讲的都是三个框架,本身,如何,操作,却只字未提,领域模型的建立.仿佛人们,学会了三个框架的技术细节,就可以开发好企业应用了。尽管Spring提供了实现领域驱动设计的潜在能力,但是,仍然,没有使人在错误的道路上。那个时候Martin Fowler提出了POLO,隐含的,说明了,创建领域模型的重要性。然而理解的人并不多,老爷子说的也不明确。这样一耽误就是十几年。90年代中期面向对象方法学的大好形势,烟消云散了。在企业应用的场合下人们退回到了,面向过程的开发方法。讽刺的是,人们使用的是java c#这样的面向对象语言。 然而这一行势必将改观。近年来,面向对象方法学,正在以领域驱动设计的面貌,重新回归大众视野,那么,为什么,领域驱动设计在沉寂了十几年之后,又能够好起来呢。
有一些,科学或者技术,在刚刚产生的时候,未必能够引起人们广泛的注意,直到各方面条件,内外因素具备之后。风云际会,才崛起。比如说,这两年,十分热门的深度学习,其理论基础,早在几十年前就已经成熟了,尽管,近年来也不乏,技术方面的创新,但是,在理论上并没有真正,突破意义的进展。而之所以能够热起来,并在实践中,产生,真正有意义的结果。在于软硬件,方面的发展,提供了,足够的,计算能力。容易使用的语言和框架。
而领域驱动设计的复兴,则来源于以下几个因素。其首要原因首推敏捷软件开发。
上文说过,领域驱动设计原书中,并没有对架构演化的能力,提出,行之有效的,办法,而这正是,领域驱动设计,得以成功的前提。敏捷软件开发,的各项实践,恰好解决这一问题。典型的包括,测试驱动开发,持续交付,重构浮现式设计,眼镜是架构等等。也包括管理方面,基于迭代和看板的开发。
第二前文提到,对于,领域,专家和,开发人员的协作。领域驱动设计,也没有提出一套完整的体系。而敏捷软件开发,最重要的,就是打破,部门之间的,壁垒。促进各种角色的协作。全功能团队。现场客户。敏捷计划会议,需求梳理,迭代评审评审会议。等等实践,为领域专家,和开发团队的,协作,提供了,一套行之有效的,方法体系。进而形成了高效协作的文化。用户地图。以及,去年刚刚产生的,事件风暴。责备,领域专家和团队的协作提供了具体的形式。
第三则是微服务架构,要求。微服务,设计的一个重要方面在于如何划分服务。这绝不像表面上看来这么容易。而另一驱动设计中的限界上下文,对这一问题,提供了,理论基础。
第四,像spring jpa等技术框架。以及,ruby on rails等等,以及后来出现的层出不穷的技术框架。是开发人员,从技术框架的细节中解放出来,可以将更多的精力投入到领域本身的,分析,和研究。
第五些,新的方法,新的技术,如cos。整洁架构。六边形架构。对领域驱动设计原先提出的技术进行了补充。
第五点,数字化转型的需求,各种老旧的项目,不能适应新的变化。
前两点解决了,领域驱动设计的内在问题,第三点,则是,外在的迫切需求。第四点提供了,外在的技术支持。这些促成了领域驱动设计,这两年重新回到大众的视野。
厘清涉及未来会怎么样呢?我认为,由于各方面条件,已经具备,另一方面,由于沥青的设计,需要解决的问题本身就是复杂的,因此,也不会特别快地普及。结论是。林青的设计,会逐渐稳健的的,在企业应用,中,普及开来。
最后,提出两个在,领域驱动设计普及中要注意的问题。领域驱动设计是建立在面向对象方法学的,基础之上的。领域驱动设计中,提出了,传统验证方法,学中,所缺失的部分,但是并没有重复,面向对象方法中,已经解决的内容。也就是面向对象,方法的,建模的基本方法和技能。因此如果读者,仅仅阅读了,领域驱动设计方面的书,而没有掌握面向对象的基础,则不可能将另行设计,真正在实践中用好。所以必须注重对面向对象,本身的掌握。这里推荐几本书?一个是不实的,面向对象分析和设计。20浪漫的,因为面膜是应用。三是,标靶c马婷的,敏捷软件开发。48天,疯了,因为没有清脆。 其他的书大家可以选图。
第二点是,用户,体验地图以及时间风暴,对于,了解业务流程。识别出,领域事件,聚合,等等还有用处。但对于,和,离专家一起,研究出,准确的,丰富的,深刻的,离模型,仍然是不足的。这一点本来是,因为妙的长项,但是对于领域专家来说,六安苗师傅似乎不够亲切。目前,我的想法是,江阴文庙最核心的部分抽取出来,以简洁的方式,在,领域专家,与开发人员的协作中,逐渐的,是另一专家掌握。注意方法,需要在实践中,逐步尝试。
最后,我怀着激动的心情,想,明天对象,早期的前辈和大师们致敬。
网友评论