DDD领域驱动设计基本理论知识总结
- 格式:docx
- 大小:126.97 KB
- 文档页数:15
《领域驱动设计》基础知识汇总(转)1. 什么是领域(Domain)我们所做的软件系统的目的都是来解决一系列问题,例如做一个电商系统来在线销售自己企业的产品;做一个灰度发布平台来提升服务的质量和稳定性。
任何一个系统都会属于某个特定的领域,例如:•论坛是一个领域:要做一个论坛,那这个论坛的核心业务是确定的:比如用户发帖、回帖等核心基本功能;•电商系统是一个领域:只要是电商领域的系统,那核心业务就是:商品浏览、购物车、下单、减库存、付款交易等核心环节;同一个领域的系统都具有相同的核心业务,因为他们要解决的问题的本质是类似的。
因此可以推断:一个领域本质上可以理解为一个问题域。
只要确定了系统所属的领域,那么这个系统的核心业务,即要解决的关键问题就基本确定了。
通常我们说,要成为一个领域的专家,必须要在这个领域深入研究很多年才行,只有这样才会遇到非常多的该领域的问题,积累了丰富的经验。
2.界限上下文(Bounded Context)通常来说,一个领域有且只有一个核心问题,我们称之为该领域的『核心子域』。
在核心子域、通用子域、支撑子域梳理的同时,会定义出子域中的『限界上下文』及其关系,用它来阐述子域之间的关系。
界限上下文可以简单理解成一个子系统或组件模块。
例如:下图是对酒店管理的子域和界限上下文的梳理:3. 领域模型(Domain Model)领域驱动设计(Domain-Driven Design)分为两个阶段:1.以一种领域专家、设计人员、开发人员都能理解的通用语言作为相互交流的工具,在交流的过程中发现领域概念,然后将这些概念设计成一个领域模型;2.由领域模型驱动软件设计,用代码来实现该领域模型;由此可见,领域驱动设计的核心是建立正确的领域模型。
领域模型具有以下特点:1.对具有某个边界的领域的一个抽象,反映了领域内用户业务需求的本质。
它属于『解决问题空间』。
领域模型是有边界的,只反应了我们在领域内所关注的部分,包括实体概念(如:货物,书本,应聘记录,地址等),以及过程概念(如:资金转账等);2.提高软件的可维护性,业务可理解性以及可重用性。
《领域驱动设计》基础知识汇总《领域驱动设计》(Domain-Driven Design,简称DDD)是一种软件开发方法论,它将软件开发过程中的关注点从技术细节转移到业务领域上。
DDD强调将业务需求和软件模型紧密对应,以便更好地理解业务需求,并将其准确地转化为可执行的软件模型。
以下是《领域驱动设计》的基础知识汇总。
1.领域驱动设计的核心思想是通过将知识转化为模型来解决复杂问题。
领域模型是对业务领域知识的抽象和表达,它将业务对象、业务规则和业务流程等概念化地表示出来。
2.领域驱动设计强调领域专家参与,并与开发团队紧密合作。
领域专家是对业务领域非常熟悉的人,他们能够提供与业务相关的知识和经验,并对软件开发过程中的需求和模型进行指导。
3.领域驱动设计提倡使用统一的语言来描述业务领域。
该语言应该由领域专家和开发团队共同创造,以最大程度地减少沟通障碍并提高开发效率。
4.领域驱动设计中的聚合是一个非常重要的概念。
聚合是一个具有内聚性的对象集合,它们被视为一个整体并按照一定的规则进行操作和管理。
聚合根是聚合中最核心的对象,它负责管理整个聚合的状态和行为。
5.领域驱动设计中的领域事件是一种重要的机制,用于解耦和通信。
领域事件是业务领域中发生的一些关键事件,它们被抽象为领域事件,并且可以被其他对象订阅和处理。
6.领域驱动设计中的领域服务是一种封装了业务逻辑的对象,它不属于任何聚合和实体,负责处理那些跨聚合的复杂业务逻辑。
领域服务可以与其他对象进行协作,但它不应该持有状态。
7.领域驱动设计中的领域模型需要经过持久化以便在不同的系统之间共享和使用。
领域模型可以通过使用ORM框架或其他数据持久化技术来实现,并根据需要进行优化。
8.领域驱动设计强调使用领域驱动设计模式来解决常见的设计问题。
这些模式包括实体、值对象、仓储、工厂、规范等,它们提供了一些通用的解决方案,可以帮助开发人员更好地组织和管理领域模型。
9.领域驱动设计需要采用迭代增量的方式进行开发,将复杂的需求拆分成小的任务,并通过测试驱动开发的方式逐步实现。
DDD(领域驱动设计)概念解析1. 概念定义领域驱动设计(Domain-Driven Design,DDD)是一种软件开发方法论,旨在通过将领域专家、开发人员和技术团队之间的沟通和合作放在首位,来解决软件开发过程中的复杂性问题。
DDD的核心思想是将软件系统划分为多个相对独立的领域,通过深入理解和建模领域来设计并开发具有高度可维护性和可扩展性的软件系统。
2. 关键概念2.1 领域(Domain)领域是指问题域中的某个业务领域或子领域,例如电商系统中的订单领域、库存领域等。
领域是DDD的核心,开发人员需要深入理解和建模领域,将重点放在解决业务问题上。
2.2 领域模型(Domain Model)领域模型是对业务领域中概念和规则的抽象和描述。
它是对领域知识和业务操作的精确表达,以及领域中各个实体、值对象、聚合、领域服务等之间的关系和交互。
领域模型旨在捕捉和表达业务底层的本质,并为软件系统的设计和实现提供指导。
2.3 战略设计(Strategic Design)战略设计是指在DDD中用于管理和组织领域模型的总体架构和边界的过程。
它主要包括定界子域、模块化架构、领域通用语言等内容。
战略设计的目标是保证领域模型的内聚性和自治性,避免领域之间的耦合和混淆。
2.4 战术设计(Tactical Design)战术设计是指在DDD中用于实现和操作领域模型的具体策略和技巧。
它关注领域模型的细节,包括实体的定义和行为、聚合的边界和规则、值对象的设计等。
战术设计的目标是支持领域模型的建模和实现,保障系统具备高内聚性、低耦合性和可扩展性。
2.5 领域驱动设计的重要性领域驱动设计具有以下重要性:2.5.1 建立和维护领域模型领域模型是软件系统的核心,它能够准确地表达业务需求和规则,并指导系统的设计和实现。
采用领域驱动设计能够帮助开发人员深入领域,理解和建模业务领域,从而建立和维护优秀的领域模型。
2.5.2 提高软件系统的可维护性和可扩展性领域驱动设计强调解耦和模块化的设计原则,通过将系统划分为多个领域模型、聚合等独立模块,提高了系统的可维护性和可扩展性。
领域驱动设计详解领域驱动设计(Domain-Driven Design,DDD)是一种软件开发方法论,旨在解决复杂领域中的问题。
它强调软件开发应该以领域为核心,将领域专家的知识融入到设计中,以便更好地理解和解决领域中的问题。
在领域驱动设计中,领域是指问题领域的具体范围,例如电子商务、银行业务等。
领域专家是在该领域中具备丰富知识和经验的人员。
通过与领域专家的密切合作,开发团队可以更好地理解和解决问题。
领域驱动设计的核心概念包括领域模型、限界上下文和聚合根。
领域模型是对领域的抽象和描述,它包含了领域中的实体、值对象、服务和领域事件等。
领域模型应该是由领域专家和开发团队共同定义和演化的,以确保模型能够准确地反映领域的实际情况。
限界上下文是指领域模型的边界,它定义了在不同上下文中的含义和范围。
一个限界上下文可以是一个子系统、一个模块或一个服务,它负责管理自己的领域模型和业务逻辑。
通过明确限界上下文,可以确保不同上下文之间的交互和协作更加清晰和有效。
聚合根是领域模型中的重要概念,它是一组相关对象的根节点。
聚合根负责维护聚合内部的一致性和完整性,并且提供了访问和操作聚合内部对象的接口。
通过聚合根,可以将复杂的领域模型分解为更小的组件,提高系统的可维护性和灵活性。
在实施领域驱动设计时,需要遵循一些基本原则和模式。
要尽量保持领域模型的简洁和清晰。
领域模型应该只包含与领域相关的概念和逻辑,避免引入与领域无关的技术细节。
同时,要注重模型的可复用性和可扩展性,以便应对未来的需求变化。
要进行持续的领域建模和迭代开发。
领域模型应该是一个持续演化的过程,通过与领域专家的交流和反馈,不断优化和完善模型。
同时,要采用敏捷开发的方法,以快速响应需求变化,并及时调整和修改领域模型。
要注重领域模型和代码的质量。
领域模型应该是可测试和可验证的,以确保模型的正确性和一致性。
同时,要采用合适的设计模式和技术,以提高代码的可读性、可维护性和可扩展性。
ddd的设计方法DDD(领域驱动设计)是一种软件设计方法,主要关注领域模型的设计和领域驱动设计原则的应用。
它强调软件设计应该反映领域模型,并将其作为核心设计元素。
在DDD中,领域模型是对业务领域的概念和规则的映射,它封装了业务逻辑和数据访问。
DDD的设计方法可以分为下面几个方面:1.领域驱动设计原则:DDD倡导将领域模型作为核心设计元素,通过使用领域模型中的领域对象、值对象和领域服务来解决问题。
此外,DDD还强调通过领域事件和领域服务来处理业务逻辑。
2.领域模型的定义:在DDD中,领域模型是对业务领域的概念和规则的映射。
通过定义领域对象(实体)、值对象和领域服务,可以捕获业务问题的本质,并将其转化为软件设计中的类和接口。
3.聚合根和聚合:聚合是领域模型中的一个重要概念,用于定义一组相关的领域对象。
聚合根是聚合中的一个特殊对象,它负责维护聚合内部对象的一致性和完整性。
通过定义聚合和聚合根,可以将复杂的业务逻辑分解为更小的单元,并实现领域驱动设计的分层结构。
4.领域事件和事件驱动架构:DDD强调使用领域事件来处理业务逻辑。
领域事件是对领域中重要的状态变化或行为的抽象,它可以用于实现事件驱动架构(EDA)和异步通信。
通过定义领域事件,可以实现领域模型的解耦和灵活性。
5.领域驱动设计的分层架构:DDD倡导将领域模型分离开来,使其成为应用程序的核心。
通过使用领域层、应用层和基础设施层,可以实现业务逻辑和技术实现的解耦。
领域层负责实现领域模型和业务规则,应用层提供应用程序的基本逻辑,基础设施层则负责与外部系统的交互。
6.测试和演进式设计:DDD强调测试驱动开发(TDD)和迭代开发,以确保软件设计的可测试性和灵活性。
通过高度可测试的领域模型和领域服务,可以实现单元测试、集成测试和端到端测试,并支持持续集成和发布。
7.组织和沟通:在DDD中,软件设计师需要与领域专家密切合作,共同开发和验证领域模型。
通过领域驱动设计的方法,可以促进软件团队内部以及与领域专家之间的有效沟通和协作。
DDD—什么是领域驱动设计领域驱动设计(Domain-Driven Design,简称DDD)是一种软件开发方法论,强调将对领域的理解和业务需求置于软件设计和开发的核心位置。
领域驱动设计的目标是通过充分理解和建模领域,实现软件系统与业务领域的高度一致性,并提高软件开发的效率和质量。
在领域驱动设计中,核心思想是将软件系统设计为由领域模型(Domain Model)驱动的系统。
领域模型是对业务领域的抽象和概念化,它反映了问题领域的核心概念、业务规则和关键流程。
通过领域模型的建立,可以更好地理解和表达业务需求,为软件开发提供明确的指导和依据。
在领域驱动设计中,首要任务是对领域进行深入了解和分析,通过与领域专家的合作,获取对领域的深入理解、业务需求和规则。
这种合作被称为“域(Domain)专家与开发者的沟通”,其中域专家负责提供业务知识,开发者则负责将其转化为可执行的软件系统。
通过这种方式,在设计和开发过程中避免了沟通和理解上的困境,确保软件系统与业务领域的一致性。
领域驱动设计强调使用领域通用语言(Ubiquitous Language)来沟通和建模。
通用语言是一套在整个软件系统中通用的、与业务相关的术语和概念。
通过使用通用语言,可以将业务需求和软件设计紧密结合起来,避免语义模糊和沟通误解。
在领域驱动设计中,领域模型是实现领域驱动设计的核心工具。
领域模型是对业务领域的抽象和建模,它由实体(Entity)、值对象(Value Object)、领域服务(Domain Service)等元素组成。
领域模型制定了业务领域的规则、行为和状态,并提供了对业务需求的有效表达和实现。
通过将领域模型转化为代码,可以建立高度一致的软件系统。
除了领域模型,领域驱动设计中还涉及到一些核心概念和模式,如聚合(Aggregate)、工厂(Factory)、仓储(Repository)、领域事件(Domain Event)等。
这些概念和模式为领域驱动设计提供了更加灵活和可扩展的开发框架,使得软件开发更加贴合业务需求。
领域驱动设计手册领域驱动设计(Domain-Driven Design,简称DDD)是一种软件设计方法论,旨在帮助开发人员更好地理解和设计复杂的软件系统。
以下是领域驱动设计的手册:1. 定义域、子域和核心域:在开始设计软件系统时,首先要明确系统的业务领域,并区分出不同的子域和核心域。
域是系统中一组相关的业务概念和业务规则的集合,子域是域的一个子集,核心域则是系统中最重要的业务概念和规则的集合。
2. 识别实体和值对象:在核心域中,需要识别出重要的业务实体和值对象。
实体是具有唯一标识的业务对象,值对象则是不可变、无唯一标识的业务对象。
3. 定义聚合和聚合根:聚合是一组相关实体的集合,聚合根是一个聚合中的实体,用于管理其他实体的生命周期。
在定义聚合时,需要明确聚合的边界和实体之间的关系。
4. 设计仓库和仓库方法:仓库是用于存储聚合的对象的集合,仓库方法则是用于访问和操作仓库中对象的函数。
仓库的设计需要考虑数据的存储、检索和更新等方面的需求。
5. 实现领域服务和应用服务:领域服务是用于处理特定业务规则和逻辑的服务,应用服务则是用于协调领域服务和用户界面之间的服务。
实现领域服务和应用服务需要遵循单一职责原则,保证服务的可测试性和可维护性。
6. 设计用户界面和API:用户界面是用户与软件系统交互的界面,API则是软件系统提供的外部接口。
设计用户界面和API需要考虑用户体验、系统安全性、可扩展性和可维护性等方面。
7. 实现数据访问层:数据访问层是用于访问和操作数据库的层,需要实现数据存储、检索和更新等功能。
实现数据访问层需要遵循数据库设计原则,保证数据的一致性、完整性和性能。
8. 进行测试和部署:在完成以上设计后,需要进行单元测试、集成测试和系统测试等不同类型的测试,确保系统的功能和性能符合要求。
测试通过后,需要进行部署和上线,保证系统能够稳定运行。
总之,领域驱动设计是一种非常实用的软件设计方法论,可以帮助开发人员更好地理解和设计复杂的软件系统。
软件架构中的领域驱动设计(DDD)领域驱动设计(DDD)是一种软件开发方法论,它将软件项目的设计和实现过程,建立在对业务领域的深入理解基础之上。
通过将业务领域的知识和经验融入到软件设计和开发的过程中,DDD可以帮助开发团队更好地理解业务需求,提高软件的质量和稳定性。
1. DDD的基本概念领域驱动设计的核心思想是将软件系统划分为不同的领域,每个领域都有自己的业务模型、规则和流程。
通过深入了解这些领域的特点和要求,开发团队可以设计出更加贴合实际需求的软件架构和系统设计。
在领域驱动设计中,通常会使用领域模型、领域事件和领域服务等概念,来帮助团队更好地理解和实现业务需求。
2. DDD的核心概念2.1领域模型领域模型是领域驱动设计的核心概念,它是对领域中各种实体、值对象、聚合和领域服务等概念的抽象和建模。
通过领域模型的建立,开发团队可以更好地理解业务逻辑和规则,从而设计出更加贴合实际需求的软件系统。
领域模型通常是通过领域专家和开发团队的合作来构建的,它是对业务需求的一种抽象和概括。
2.2领域事件领域事件是领域驱动设计中的另一个核心概念,它是描述领域中事件发生和影响的概念。
通过将领域中的各种事件进行抽象和建模,开发团队可以更好地理解各种业务规则和流程,从而设计出更加稳定和可靠的软件系统。
领域事件通常是领域模型的一部分,它描述了业务领域中的各种重要事件和影响。
2.3领域服务领域服务是领域驱动设计中的另一个重要概念,它是对业务领域中某些重要操作和逻辑的抽象和建模。
通过领域服务,开发团队可以更好地处理各种业务逻辑和操作,从而设计出更加灵活和可扩展的软件系统。
领域服务通常是领域模型的一部分,它描述了业务领域中的各种重要操作和逻辑。
3. DDD的应用实践在日常的软件开发过程中,领域驱动设计可以帮助开发团队更好地理解和实现业务需求,提高软件系统的质量和稳定性。
在应用领域驱动设计的实践中,通常会涉及到以下几个方面的工作:3.1领域分析和建模领域分析和建模是领域驱动设计的重要环节,它通过与业务专家的沟通和合作,来深入了解业务领域的特点和要求,从而建立起相应的领域模型、领域事件和领域服务等概念。
什么是领域驱动设计(DDD)架构领域驱动设计(Domain-Driven Design,DDD)架构是一种软件开发方法论,通过将软件设计过程中的关注点放在问题领域本身上,以更好地满足业务需求和解决复杂性问题。
DDD架构注重表达业务概念,并在技术实现中对其进行建模和映射,以便更好地理解和满足业务需求。
DDD架构的核心理念是将领域专家(Domain Experts)和技术人员聚集在一起,通过有效的沟通和合作,共同开发具有高内聚性和松耦合性的软件系统。
为了实现这一目标,DDD提供了一些关键概念和设计原则,下面将介绍其中的几个。
1. 领域模型(Domain Model):领域模型是DDD架构中最重要的概念之一。
它是对业务领域中的重要概念、规则和关系的抽象和建模。
通过领域模型,我们可以深入理解业务需求,将其转化为可执行的软件模型。
2. 聚合(Aggregates):聚合是领域模型中的一个重要概念,表示一组相关的对象或实体。
聚合内的对象之间有着明确的边界和关联关系,外部对象只能通过聚合根(Aggregate Root)来访问聚合内的其他对象。
这样可以确保数据的一致性和完整性。
3. 领域事件(Domain Events):领域事件是对领域模型中重要业务动作的建模,它表示在领域中发生的一些重要事情。
领域事件可以触发其他领域对象的行为,也可以被其他领域对象所订阅和处理。
通过领域事件,我们可以实现领域模型中的业务流程和逻辑。
4. 值对象(Value Objects):值对象是DDD中用于表示没有标识的、可替换的对象。
它们通常被用来描述领域模型中的属性或者一些固定的、不可变的值。
值对象具有值的语义,可以通过比较其属性来判断对象是否相等。
5. 聚合根和仓储(Aggregate Roots and Repositories):聚合根是聚合中的一个重要对象,负责协调和控制聚合内的其他对象。
仓储则是将聚合根和聚合内的其他对象持久化到数据库或其他存储介质中的组件。
DDD—什么是领域驱动设计⼀、DDD从放弃到⼊门希望了解⼀套微服务框架的;希望学习到新技术的;开发的系统不复杂,模块少⽽独⽴的;当前⾃⼰设计的架构已满⾜拓展性,可复⽤性,技术与业务复杂度已分离的;这⼏类⼈群不是DDD的⽬标⼈群,建议尽早放弃,学习领域驱动设计能得到的收获概括起来⼤致如下:1、领域驱动设计是⼀套系统的设计思想,规范你的设计过程2、领域驱动设计⽤于处理模块繁杂,业务复杂度⾼的产品研发,旨在将将业务复杂度与技术复杂度分离,抽离出业务各个领域的核⼼内核,便于领域知识的复⽤3、领域驱动设计强调技术专家和业务专家,通过统⼀的语⾔来完成领域的建模,帮助技术侧和业务侧形成⼀套统⼀的语⾔4、微服务与领域驱动设计天然搭配,微服务拆分中⼀直模糊的边界,可通过领域驱动设计来划分清楚5、领域驱动设计能帮助提⾼⼤型系统的拓展和演进能⼒⼆、什么是DDD如下图,传统的敏捷开发模式,我们更多的使⽤数据驱动设计的思想,按照功能模块来,拆分成⼀个个的⼩模块,每个模块要实现什么功能,需要什么样的数据,然后就通过ER数据建模,建库建表后开⼲了,这样会导致N个系统中重复的功能会反复建设,Service层编写了繁杂的业务逻辑,耦合度极⾼,经常牵⼀发⽽动全⾝。
⽽DDD是指需求输⼊的时候,从领域开始聊起,⽐如教育是⼀个领域,先从校长聊起,然后聊到他的关联实体⽼师,学⽣,考试等等,这些实体之间的关联关系是什么,他们各⾃都会有哪些⾏为⽅法和业务逻辑。
聊清楚后进⾏实体的建模,聚合实体的⾏为形成⼀个个领域服务,⽐如学⽣+⽼师的实体组合成了上课这⼀领域服务,之后再对领域服务进⾏编排,组成核⼼的可复⽤的业务逻辑。
再之后就是经过领域模型划分微服务界限,映射模型和微服务代码后进⾏开发,DDD就是以领域为⼊⼝,来解决产品设计,研发的思想。
DDD通过领域建模,编排核⼼业务逻辑后映射到微服务开发的过程,有利于构建出企业可复⽤的核⼼能⼒,减少重复的IT建设,同时开发者可以根据模型和微服务代码设计的对应关系,快速清晰的完成开发。
▪领域驱动设计之领域模型▪为什么建立一个领域模型是重要的▪领域通用语言(UBIQUITOUS LANGUAGE)▪将领域模型转换为代码实现的最佳实践▪领域建模时思考问题的角度▪领域驱动设计的经典分层架构▪用户界面/展现层▪应用层▪领域层▪基础设施层▪领域驱动设计过程中使用的模式▪所有模式的总揽图▪关联的设计▪实体(Entity)▪值对象(Value Object)▪领域服务(Domain Service)▪应用层服务▪领域层服务▪基础层服务▪聚合及聚合根(Aggregate,Aggregate Root)▪聚合有以下一些特点:▪如何识别聚合?▪如何识别聚合根?▪工厂(Factory)▪仓储(Repository)▪设计领域模型的一般步骤▪在分层架构中其他层如何与领域层交互▪对于会影响领域层中领域对象状态的应用层功能▪关于Unit of Work(工作单元)的几种实现方法▪对于不会影响领域层中领域对象状态的查询功能▪为什么面向对象比面向过程更能适应业务变化▪领域驱动设计的其他一些主题▪一些相关的扩展阅读▪CQRS架构▪Event Sourcing(事件溯源)▪DCI架构▪四色原型分析模式▪时刻-时间段原型(Moment-Interval Archetype)▪参与方-地点-物品原型(Part-Place-Thing Archetype)▪描述原型(Description Archetype)▪角色原型(Role Archetype)领域驱动设计之领域模型加一个导航,关于如何设计聚合的详细思考,见这篇文章。
2004年Eric Evans 发表Domain-Driven Design –Tackling Complexity in the Heart of Software (领域驱动设计),简称Evans DDD。
领域驱动设计分为两个阶段:以一种领域专家、设计人员、开发人员都能理解的通用语言作为相互交流的工具,在交流的过程中发现领域概念,然后将这些概念设计成一个领域模型;由领域模型驱动软件设计,用代码来实现该领域模型;由此可见,领域驱动设计的核心是建立正确的领域模型。
为什么建立一个领域模型是重要的领域驱动设计告诉我们,在通过软件实现一个业务系统时,建立一个领域模型是非常重要和必要的,因为领域模型具有以下特点:1.领域模型是对具有某个边界的领域的一个抽象,反映了领域内用户业务需求的本质;领域模型是有边界的,只反应了我们在领域内所关注的部分;2.领域模型只反映业务,和任何技术实现无关;领域模型不仅能反映领域中的一些实体概念,如货物,书本,应聘记录,地址,等;还能反映领域中的一些过程概念,如资金转账,等;3.领域模型确保了我们的软件的业务逻辑都在一个模型中,都在一个地方;这样对提高软件的可维护性,业务可理解性以及可重用性方面都有很好的帮助;4.领域模型能够帮助开发人员相对平滑地将领域知识转化为软件构造;5.领域模型贯穿软件分析、设计,以及开发的整个过程;领域专家、设计人员、开发人员通过领域模型进行交流,彼此共享知识与信息;因为大家面向的都是同一个模型,所以可以防止需求走样,可以让软件设计开发人员做出来的软件真正满足需求;6.要建立正确的领域模型并不简单,需要领域专家、设计、开发人员积极沟通共同努力,然后才能使大家对领域的认识不断深入,从而不断细化和完善领域模型;7.为了让领域模型看的见,我们需要用一些方法来表示它;图是表达领域模型最常用的方式,但不是唯一的表达方式,代码或文字描述也能表达领域模型;8.领域模型是整个软件的核心,是软件中最有价值和最具竞争力的部分;设计足够精良且符合业务需求的领域模型能够更快速的响应需求变化;领域通用语言(UBIQUITOUS LANGUAGE)我们认识到由软件专家和领域专家通力合作开发出一个领域的模型是绝对需要的,但是,那种方法通常会由于一些基础交流的障碍而存在难点。
开发人员满脑子都是类、方法、算法、模式、架构,等等,总是想将实际生活中的概念和程序工件进行对应。
他们希望看到要建立哪些对象类,要如何对对象类之间的关系建模。
他们会习惯按照封装、继承、多态等面向对象编程中的概念去思考,会随时随地这样交谈,这对他们来说这太正常不过了,开发人员就是开发人员。
但是领域专家通常对这一无所知,他们对软件类库、框架、持久化甚至数据库没有什么概念。
他们只了解他们特有的领域专业技能。
比如,在空中交通监控样例中,领域专家知道飞机、路线、海拔、经度、纬度,知道飞机偏离了正常路线,知道飞机的发射。
他们用他们自己的术语讨论这些事情,有时这对于外行来说很难直接理解。
如果一个人说了什么事情,其他的人不能理解,或者更糟的是错误理解成其他事情,又有什么机会来保证项目成功呢?在交流的过程中,需要做翻译才能让其他的人理解这些概念。
开发人员可能会努力使用外行人的语言来解析一些设计模式,但这并一定都能成功奏效。
领域专家也可能会创建一种新的行话以努力表达他们的这些想法。
在这个痛苦的交流过程中,这种类型的翻译并不能对知识的构建过程产生帮助。
领域驱动设计的一个核心的原则是使用一种基于模型的语言。
因为模型是软件满足领域的共同点,它很适合作为这种通用语言的构造基础。
使用模型作为语言的核心骨架,要求团队在进行所有的交流是都使用一致的语言,在代码中也是这样。
在共享知识和推敲模型时,团队会使用演讲、文字和图形。
这儿需要确保团队使用的语言在所有的交流形式中看上去都是一致的,这种语言被称为“通用语言(Ubiquitous Language)”。
通用语言应该在建模过程中广泛尝试以推动软件专家和领域专家之间的沟通,从而发现要在模型中使用的主要的领域概念。
将领域模型转换为代码实现的最佳实践拥有一个看上去正确的模型不代表模型能被直接转换成代码,也或者它的实现可能会违背某些我们所不建议的软件设计原则。
我们该如何实现从模型到代码的转换,并让代码具有可扩展性、可维护性,高性能等指标呢?另外,如实反映领域的模型可能会导致对象持久化的一系列问题,或者导致不可接受的性能问题。
那么我们应该怎么做呢?我们应该紧密关联领域建模和设计,紧密将领域模型和软件编码实现捆绑在一起,模型在构建时就考虑到软件和设计。
开发人员会被加入到建模的过程中来。
主要的想法是选择一个能够恰当在软件中表现的模型,这样设计过程会很顺畅并且基于模型。
代码和其下的模型紧密关联会让代码更有意义并与模型更相关。
有了开发人员的参与就会有反馈。
它能保证模型被实现成软件。
如果其中某处有错误,会在早期就被标识出来,问题也会容易修正。
写代码的人会很好地了解模型,会感觉自己有责任保持它的完整性。
他们会意识到对代码的一个变更其实就隐含着对模型的变更,另外,如果哪里的代码不能表现原始模型的话,他们会重构代码。
如果分析人员从实现过程中分离出去,他会不再关心开发过程中引入的局限性。
最终结果是模型不再实用。
任何技术人员想对模型做出贡献必须花费一些时间来接触代码,无论他在项目中担负的是什么主要角色。
任何一个负责修改代码的人都必须学会用代码表现模型。
每位开发人员都必须参与到一定级别的领域讨论中并和领域专家联络。
领域建模时思考问题的角度“用户需求”不能等同于“用户”,捕捉“用户心中的模型”也不能等同于“以用户为核心设计领域模型”。
《老子》书中有个观点:有之以为利,无之以为用。
在这里,有之利,即建立领域模型;无之用,即包容用户需求。
举些例子,一个杯子要装满一杯水,我们在制作杯子时,制作的是空杯子,即要把水倒出来,之后才能装下水;再比如,一座房子要住人,我们在建造房子时,建造的房子是空的,唯有空的才能容纳人的居住。
因此,建立领域模型时也要将用户置于模型之外,这样才能包容用户的需求。
所以,我的理解是:1.我们设计领域模型时不能以用户为中心作为出发点去思考问题,不能老是想着用户会对系统做什么;而应该从一个客观的角度,根据用户需求挖掘出领域内的相关事物,思考这些事物的本质关联及其变化规律作为出发点去思考问题。
2.领域模型是排除了人之外的客观世界模型,但是领域模型包含人所扮演的参与者角色,但是一般情况下不要让参与者角色在领域模型中占据主要位置,如果以人所扮演的参与者角色在领域模型中占据主要位置,那么各个系统的领域模型将变得没有差别,因为软件系统就是一个人机交互的系统,都是以人为主的活动记录或跟踪;比如:论坛中如果以人为主导,那么领域模型就是:人发帖,人回帖,人结贴,等等;DDD的例子中,如果是以人为中心的话,就变成了:托运人托运货物,收货人收货物,付款人付款,等等;因此,当我们谈及领域模型时,已经默认把人的因素排除开了,因为领域只有对人来说才有意义,人是在领域范围之外的,如果人也划入领域,领域模型将很难保持客观性。
领域模型是与谁用和怎样用是无关的客观模型。
归纳起来说就是,领域建模是建立虚拟模型让我们现实的人使用,而不是建立虚拟空间,去模仿现实。
以Eric Evans(DDD之父)在他的书中的一个货物运输系统为例子简单说明一下。
在经过一些用户需求讨论之后,在用户需求相对明朗之后,Eric这样描述领域模型:1.一个Cargo(货物)涉及多个Customer(客户,如托运人、收货人、付款人),每个Customer承担不同的角色;2.Cargo的运送目标已指定,即Cargo有一个运送目标;3.由一系列满足Specification(规格)的Carrier Movement(运输动作)来完成运输目标;从上面的描述我们可以看出,他完全没有从用户的角度去描述领域模型,而是以领域内的相关事物为出发点,考虑这些事物的本质关联及其变化规律的。
上述这段描述完全以货物为中心,把客户看成是货物在某个场景中可能会涉及到的关联角色,如货物会涉及到托运人、收货人、付款人;货物有一个确定的目标,货物会经过一系列列的运输动作到达目的地;其实,我觉得以用户为中心来思考领域模型的思维只是停留在需求的表面,而没有挖掘出真正的需求的本质;我们在做领域建模时需要努力挖掘用户需求的本质,这样才能真正实现用户需求;关于用户、参与者这两个概念的区分,可以看一下下面的例子:试想两个人共同玩足球游戏,操作者(用户)是驱动者,它驱使足球比赛领域中,各个“人”(参与者)的活动。
这里立下一个假设,假设操作者A操作某一队员a,而队员a拥有着某人B的信息,那么有以下说法,a是B的镜像,a是领域参与者,A是驱动者。
领域驱动设计的经典分层架构用户界面/展现层负责向用户展现信息以及解释用户命令。
更细的方面来讲就是:1.请求应用层以获取用户所需要展现的数据;2.发送命令给应用层要求其执行某个用户命令;应用层很薄的一层,定义软件要完成的所有任务。
对外为展现层提供各种应用功能(包括查询或命令),对内调用领域层(领域对象或领域服务)完成各种业务逻辑,应用层不包含业务逻辑。