领域驱动设计的关注重心是领域,尤其在面对复杂的领域逻辑时,它总能够帮助我们很好地分析领域。领域驱动设计的基础是领域建模。Eric认为需要和领域专家良好地合作,从交谈中发现通用语言,找到领域的关键词。领域建模是迭代的过程,根据逐渐深入的领域知识来精化模型。不过,领域驱动设计并不排斥其他的分析技术,例如分析模式,或者通过测试驱动开发来引导我们找到问题域的领域模型。领域建模并非领域驱动设计所独有。在RUP中,领域建模就是一个非常重要的环节。它是一种用例驱动的开发方法,通过获得的用例来帮助分析和设计人员寻找对象,以及对象之间的关系。根据我个人的经验,我喜欢采用两种截然不同的方式来获得模型。一种是用例驱
领域驱动设计(Domain-Driven Design,简称DDD)是一种软件开发方法,主要关注点在于业务领域,旨在通过深入理解和建模复杂的业务逻辑来提高软件的可读性和可维护性。其核心在于领域建模,即通过与领域专家的合作,提炼出业务的通用语言,识别关键概念和规则,构建出反映领域知识的模型。
在实践中,领域建模是一个迭代过程,随着对领域理解的深入,模型会逐步完善。Eric Evans在其著作中强调了与领域专家的有效沟通,这是发现领域关键词和通用语言的关键。同时,领域驱动设计并不排斥其他分析技术,如分析模式或测试驱动开发(TDD),它们可以辅助我们构建和验证领域模型。
领域建模在Rational Unified Process(RUP)中也占有重要地位,采用用例驱动的方法,通过用例来识别对象及其相互关系。作者个人经验中,有两种获取模型的方法:用例驱动和测试驱动。在构建初步模型后,利用DDD的思想对对象进行分类,如实体(Entity)、值对象(Value Object)、聚合(Aggregate)和服务(Service),并考虑对象的生命周期,创建相应的资源库和工厂对象。
以图书馆管理系统为例,我们可以分析两个主要的用例——借书和还书。通过分析用例,我们可以识别出Reader、Administrator、Book、Library Card和Scanner等对象。在这个过程中,我们可以发现Scanner对象更适合作为服务对象,因为它只关注扫描行为,而不关心具体的对象。而Reader与Book之间的关系通过Library Card得以体现,Reader对象可以进一步细化,引入BorrowingHistory对象来记录借阅历史,满足查看历史记录的需求。此外,FineCalculator服务负责计算超期罚款。
在确定领域模型的实体和值对象时,需要确保每个对象都有其独特的身份(对于实体)或不变性(对于值对象)。例如,Reader需要一个唯一标识,而BorrowingHistory与特定的Book关联,形成一对一的关系。
领域驱动设计不仅仅是建模,还包括如何组织代码结构,如将领域模型放在核心层,基础设施层处理与外部系统的交互,应用层协调领域模型和用户界面。此外,界限上下文(Bounded Context)的概念用于定义模型的边界,确保在不同的业务场景下使用适当的模型。
领域驱动设计是一种深入理解业务,以业务为中心的软件开发方法。它强调与领域专家的紧密协作,通过迭代建模和多种技术结合,构建出能够准确反映业务逻辑的软件架构。在实际项目中,我们需要不断迭代和调整模型,确保模型的完整性和准确性,以支持业务的发展和变化。