领域驱动设计(Domain-Driven Design DDD)——运用领域模型

一、概述

        领域模型是关注用户需开发软件的问题区域,把需解决问题密切相关的方面抽象出来,是对领域相关知识的严格组织和有选择的抽象,是出于开发软件的目的而概括地反映问题区域。

        领域模型会有意地忽略无关细节,会对复杂的领域相关知识进行选择性的简化和有意的结构化,可以使用团队所有成员都能理解信息的意义,并专注于问题。

        领域驱动设计(Domain-Driven Design DDD)在面向对象分析设计(OOA\D)和职责驱动设计(RDD)基础上,对软件分析、设计、构造的过程进行了进一步的归纳、抽象、细化,并更加注重和强调领域模型是需求模型和软件设计模型深度绑定的软件设计方法。从而使软件开发的全生命周期不会与需解决问题的区域产生偏离,关注用户的核心痛点,生产出用户及大部分项目干系人满意的软件系统,并且减少软件开发项目失败的概率。

        一方面领域模型专注于要解决的问题领域,可以使用统一领域语言与领域专家、非IT团队成员沟通、交互。

        另一方面领域模型又便于设计实现,在某个领域模型的基础上,可以较快捷地设计软件概念上的实现模型,偏向于同编码实现的团队成员沟通交流,并且希望领域模型与这一过程深度绑定。

        为实现以上目的,领域模型需实现以下几个作用。

二、消化领域知识,模型是浓缩的知识

        知识消化并非一项孤立的活动,它一般是在开发人员的领导下,由开发人员与领域专家组成的团队来共同协作。高效的领域建模人员是知识的消化者。他们在大量信息中探寻有用的部分,他们不断尝试各种信息组织方式,努力寻找对大量信息有意义的简单视图。很多模型在尝试后被放弃或改造,直到发现一组适用于所有细节的抽象概念后,建模工作才算成功。

        在传统的瀑布方法中,领域专家先与系统分析员进行讨论,分析员消化理解这些知识后,对其进行抽象并将结果传递给程序员,再由程序员编码实现。这种方法的弊端是完全没有反馈与跟踪,是知识的单向流动,所以项目失败的概率较大。

        有些项目使用了迭代过程,若开发人员只是听专家们的描述然后就开始构建软件,则会进入没有对知识进行抽象而无法建立知识体系的误区。开发人员需要不断消化并抽象知识,充分反映领域专家的思想,才能构建一个能完成更多工作的合适模型。

        在团队所有成员一起消化理解模型的过程中,他们之间的交互也会发生变化。领域模型的不断精化迫使开发人员学习重要的业务原理、领域专家提炼自己的重要知识。他们不断磨合精进,分析员、程序员、领域专家都将自己的知识输入到了模型中,因此模型即反映了业务的深层次知识,也更加组织严密、抽象和整洁。

        模型在不断改进的同时,也成为组织项目信息流的工具。模型聚焦于问题区域的需求分析,同时与设计和编程紧密交互。这种良性交互迭代的过程,会使领域模型更加完善且易于实现和理解。

        高效的团队需要有意识的积累知识,并持续学习。而善于自学的团队成员会成为团队的中坚力量,涉及最关键领域的开发任务要靠他们来攻克。这个核心团队头脑中积累的知识使他们成为更高效的知识消化者。

三、交流与语言的使用,模型是团队所有成员使用的通用语言的中枢

        想要创建一种灵活的、蕴含丰富知识的设计,需要一种通用的、共享的团队语言(Ubiquitous Language),以及对语言不断的试验改进——然而,软件项目上很少出现这样的试验。项目需要一种公共语言,通过团队一致努力,领域模型可以成为这种公共语言的核心,最后实现项目的“一个团队,一种语言”。

        领域模型是一组得自于项目人员头脑中的概念,以及反映了领域深层含义的术语和关系。这些术语和相互关系提供了模型语言的语义,虽然语言是为领域模型量身定制的,但就技术开发而言,其依然足够精确。正是这条至关重要的纽带,将模型与开发活动结合在一起,并使模型与代码紧密绑定。

        Ubiquitous Language(通用语言)的语汇包括类和主要操作的名称。语言中的术语有些用来讨论模型中已经有明确的规则(如统一概念、关键字、编码原则等),还有一些则来自施加于模型上的高级组织原则。最后,团队常常应用于领域模型的模式名称也使这种语言更为丰富。

        为了最有效地使用模型,需要充分利用各种交流手段。并不局限于UML图,也可以是简洁的文档、非正式图表和交谈。

        因此:

        将模型作为语言的支柱。确保团队在内部的所有交流中以及代码中坚持使用这种语言。在画图、写东西,特别是交谈时也要使用这种语言。
        通过尝试不同的表示方法(它们反映的备选模型)来消除难点。然后重构代码,重新命名类、方法和模块,以便与新模型保持一致。解决交谈中的术语混淆问题,就像我们对普通词汇形成一致的理解一样。
        要认识到, Ubiquitous Language的更改就是对模型的更改。
        领域专家应该抵制不合适或无法充分表达领域理解的术语或结构,开发人员应该密切关注那些将会妨碍设计的有歧义和不一致的地方。

        有了 Ubiquitous Language(通用语言),模型就不仅仅是一个设计工件了。它成为开发人员和领域专家共同完成的每项工作中不可或缺的部分。通用语言以动态形式传递知识。使用这种语言进行讨论能够呈现图和代码背后的真实含义。

        例如:有了通用语言领域专家可以用模型语言来编写用例,甚至可以直接利用模型来具体说明验收、测试的详细要求等需求,使领域专家能更深度地溶入软件的设计开发工作。
        同样,开发人员可以和领域专家一起使用模型对象来走查场景,对模型进行非正式的测试,从而加深彼此的理解和对概念进行精化,可大大提高软件设计开发的效率。

四、绑定模型和实现,模型和设计的核心互相影响

        若项目没有建立领域模型,仅靠编码来实现功能,那么它们无法利用消化知识和沟通所带来的好处,涉及复杂领域的项目就会举步维艰。

        在传统的瀑布模型中,需求模型和程序设计之间被人为的分成二个阶段,在创建模型时没有考虑程序设计的问题,因此分析模型很有可能无法满足程序设计的要求。同样在程序设计和实现过程中总是会发现一些关键的细节和知识点,在建模阶段被忽略了。无论什么原因,软件的设计如果缺乏对应的领域模型,那么软件充其量不过是一种机械化的产品——只有实现有用的功能却无法解释为什么要这样做。

        如果整个程序设计或者其核心部分没有与领域模型相对应,那么这个模型就是没有价值的,软件的正确性也是值得怀疑。同时,模型和设计功能之间过于复杂的对应关系也是难以理解的,在实际项目中,当设计改变时也无法维护这种关系。若分析与设计之间产生严重分歧,那么在分析和设计活动中所获得的知识就无法彼此共享。

1、模式:Model-Driven Design

        Model-Drive Design(模型驱动设计)不再将分析模型和程序设计分离开,而是寻求一种能够满足这两方面需求的单一模型。不考虑纯粹的技术问题,程序设计中的每个对象都反映了模型中所描述的相应实体概念。这要求我们以更高的标准来选择模型,因为它必须同时满足两种完全不同的目标。

        有很多方法可以对领域进行抽象,也有很多种设计可以解决应用程序的问题。因此,绑定模型和程序设计是切实可行的。在模型和程序设计绑定的场景下,建模和程序设计就结合为一个统一的迭代开发过程。

        将领域模型和程序设计紧密联系在一起也是绝对必要的,这也会成为模型选择的一条标准。通过多次反复修改和重新构建,我们可以得到与程序设计相关联的模型。

        因此:

        软件系统各个部分的设计应该忠实地反映领域模型,以便体现出这二者之间的明确对应关系。我们应该反复检查并修改模型,以便软件可以更加自然地实现模型,即使想让模型反映出更深层次的领域概念时也应如此。我们需要的模型不但应该满足这两种要求,还应该能够支持健壮的Ubiquitous Language(通用语言)。
        从模型中获取用于程序设计和基本职责分配的术语。让程序代码成为模型的表达,代码的改变可能会是模型的改变。而其影响势必要波及接下来相应的项目活动。
        完全依赖模型的实现通常需要支持建模范式的软件开发工具和语言,比如Visio架构版、OOA/D等。

2、建模范式和工具支持

        为了使Model-Driven Design发挥作用,一定要在可控范围内严格保证模型与设计之间的一致性。要实现这种严格的一致性,必须要运用由软件工具支持的建模范式,它可以在程序中直接创建模型中的对应实体。

        面向对象编程之所以功能强大,是因为它基于建模范式,并且为模型构造提供了实现方式。如上图所示,从程序员的角度来看,对象真实存在于内存中,它们与其他对象相互联系,它们被组织成类,并且通过消息来完成相应的行为。而这些类与模型中的实体是一一对应的,这样非常方便模型与设计的深度绑定。

3、模式:Hands-On Modeler(亲身实践的建模者)

        人们总是把软件开发比喻成制造业,其经验是让经验丰富的工程师做设计工作,而技能水平较低的劳动力负责组装产品。这种将分析、建模、设计和编程过度分离的方式会对Model-Driven Design产生不良影响。其原因有二,一、模型的有些意图在传递过程中丢失了;二、程序实现及技术的影响无法及时反馈给模型。因此,如果不让建模人员参与程序实现,则整个团队无法有效地工作。

        因此:

        任何参与建模的技术人员,不管在项目中的主要职责是什么,都必须花时间了解代码。任何负责修改代码的人员则必须学会用代码来表达模型。每一个开发人员都必须不同程度地参与模型讨论并且与领域专家保持联系。参与不同工作的人都必须有意识地通过Ubiquitous Language与接触代码的人及时交换关于模型的想法。

        

五、领域驱动设计需要详尽的设计决策

        将建模和编程过程完全分离是行不通的,然而大型项目依然需要技术负责人来协调高层次的设计和建模,并帮助做出最困难或最关键的决策。

        Model-Driven Design利用模型来为应用程序解决问题。项目组通过知识消化将大量杂乱无章的信息提炼成实用的模型。而Model-Driven Design将模型和实现过程紧密结合。Ubiquitous Language则成为开发人员、领域专家和软件产品之间的沟通渠道。

        最终的软件产品能够在完全理解核心领域的基础上提供丰富的功能,以满足项目干系人的需求。

        如上所述,Model-Driven Design的成功离不开详尽的设计决策。

六、参考文章

DOMAIN-DRIVERN DESIGN
TACKLING COMPLEXITY IN THE HEART OF SOFTWARE

领域驱动设计
软件核心复杂性应对之道

【美】Eric Evans 著   赵俐 盛海艳 刘霞 等 译

  • 24
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
领域驱动设计Domain-Driven DesignDDD)是一种软件开发方法论,旨在帮助开发团队更好地理解业务需求,并将其映射到软件设计中。"Patterns, Principles, and Practices of Domain-Driven Design" 是一本介绍DDD的书籍。 该书包含了许多相关的模式(patterns),原则(principles)和实践(practices)。模式指的是可重复应用的最佳实践,通过使用这些模式可以更好地解决一些常见的设计问题。原则则是指导设计决策的基本原则,这些原则有助于开发团队构建可维护、灵活和可扩展的软件。实践则是指在DDD中应用这些模式和原则的具体方法和技巧。 在"Patterns, Principles, and Practices of Domain-Driven Design" 中,作者将介绍如何使用DDD来进行软件开发,并详细解释了DDD的核心概念和重要组成部分。这包括战略设计(Strategic Design)和战术设计(Tactical Design)。战略设计关注领域的整体架构和组织,它定义了领域的边界、聚合根(Aggregate Roots)以及他们之间的关系。而战术设计则关注如何实现具体的业务逻辑,使用领域模型Domain Model)来表达领域的核心概念。 该书强调了领域专家和开发团队之间的合作,推崇的是通过持续对话和深入理解业务,来捕捉业务需求和规则。它提倡使用通用语言(Ubiquitous Language)来统一业务和开发团队的沟通,避免因为术语不清晰而导致的误解和问题。 总之,"Patterns, Principles, and Practices of Domain-Driven Design" 提供了一个全面的指南,帮助开发团队理解和应用DDD的模式、原则和实践,以构建高质量、符合业务需求的软件系统

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值