软件开发过程之构建领域模型泛谈

   领域驱动设计的话题已经被讨论了许多年了,拿出来讨论建模方式,多少有种炒冷饭的嫌疑。但是在实际的应用中,我们为了实现业务软件的可伸缩性和分层维护,或者在业务实现的过程中,通过迭代不断的深入理解业务需求,个中技巧往往又都是DDD最迷人的特性。
第一部分 领域建模
    在一个软件开发周期中,为了更好的管理软件开发过程,时下最流行的方式莫过于沿用SCRUM敏捷框架。敏捷的短周期持续化交付往往是业内大多数开发经理人口中深入理解和控制需求的法宝。人们之所以选择敏捷开发,主要原因就是我们的需求提供者和开发人员在理解自己需要实现的东西上,往往都存在着很模糊的认识,项目的参与者心知肚明,但碍于大家在语意沟通上存在着业务鸿沟,我们无法在初期就能准确的得到需求模型。因此,敏捷开发就像是作画一样,先画出一个大的轮廓,然后画出一部分,给客户看一部分,尽早发现错误尽早修正,这样在时间和精确程度上往往能够达到事半功倍的效果。
   OK,这样想非常好!然而在这段描述中我们可以注意到,需求准确性是那么重要,但是却要涉及到开发过程中才可以得到确认并修正,这不是给我们的开发人员增加了额外的工作负担?虽然这样的事情在所难免,然而这样的事情依然会导致项目的时间风险和经费上的浪费,并且我相信没有程序员会愿意为此买单。因此,我们的领域专家Eric Evens整理并提出了领域建模的想法。这个想法的好处就是在迭代开发之前,先来和业务专家们勾描我们将要设计的业务模型是个什么样子,通过沟通而非实现,使业务专家们认识到他们的软件将实现出一个什么样的需求来,需求上的错误认知发现的越早,我们项目的损失也就越小。那么问题来了,我们如何与业务专家沟通呢?
第二部分 统一建模语言
     在业务专家眼中,往往业务描述都是从一个业务操作人员角度开始,通过不断的操作动作,最终实现了一个或多个客户可以满意的结果。这样的过程他们有行业上固定的用语,甚至是公司内部的描述语言。而这对于开发人员来说,这些用于无异于二战时期的密文电码,反之,业务专家眼中技术人员的描述亦然。因此,想要很好的沟通,我们只有知道如何翻译它,才可以理解它。统一建模语言的方式,就是要在两种术语之间架起一个翻译的字典,抓住关键的语句和动作词汇,把它们放在字典中,然后双方把对它们的认知统一起来,OK,这下大家说什么也就没有障碍了,沟通可以继续了。
      那么以后再有不懂的词汇呢?继续放在字典中,不断的丰富它们就好。
 第三部分  建立模型
     当我们把这本字典整理好后,下一步就该谈到如何用了。
     首先,我们需要将这些领域词汇提取出来,写在白板上,然后请业务专家告诉我们,这些词汇之间的关系。例如:“客户”与“产品”,“票据”与“帐套”,“借款”与“贷款”等等;他们一边说,我们一边用类图之类的关联关系将这些对象连接起来。
     然后当关系都建立完成后,再一一的复述给业务人员听,确保他们认可;之后双方通过不断的沟通理解,很快业务模型就可以被梳理出来。然后,我们就可以骄傲的告诉他们,我们的程序设计就是如此进行。
 第四部分  模型实现
     光有模型图对于我们软件开发来说还远远不够,我们的设计师们还要将他们转换为实际的业务对象进行编码,那么如何转换呢?在领域模型中,我们有一些基础的模型元素,他们分别为:entry(实体)、ValueObject(值对象)和Service(服务);他们的颗粒细度依次是:VO<Entry<Service;
     1、VO:作为模型中的属性值的存在;
     2、Entry:作为模型中真实业务主体(有唯一标识且可追溯、有生命周期);
     3、Service:模型中主体与外界业务发生的动作;
     领域模型通过以上三种基本元素丰富起来。
 第五部分 模型的生命周期
     模型为表达业务,其生命周期主要是围绕Entry(实体)存在。实体的生命周期包括创建、引用、脱离和销毁;实体本身根据业务编排需要,既会被引用,也会引用其它业务实体;而围绕它自身的属性和动作则分别有VO和Serive对象来负责;这样的一个功能群被有意的聚合在一起,在Eric的书中给了一个定义,称之为“aggregate”,aggregate有唯一的stub(根),还有用来约束自身行为的bound(边界);集合的根是外围调用唯一访问集合的点,它本身就是一个Entry,而这个Entry的ID应该在集合的内外都应该是唯一的。
     并且,当这个stub被销毁时,这个集合也应该一并被销毁;其模型上的数据也应该被事务提交到持久化层中去。
结尾
      至此,我们的业务模型基本算是完成,剩下的事情就是不断的完善和修订这个模型,而程序也会在模型完善过程中不断的被改善。并且,由于领域模型中,业务实体是高度集合化的,因此符合高内聚、低耦合特点,因此可以用模块化将其服务打包,便于整体项目的伸缩性和可维护性。

参考:Eric Evans的《领域驱动设计 -- 软件核心复杂性应对之道

猜你喜欢

转载自louis0001.iteye.com/blog/1290347