通用语言
通用语言
在 DDD 领域建模和系统建设过程中,有很多的参与者,包括领域专家、产品经理、项目经理、架构师、开发经理和测试经理等。对同样的领域知识,不同的参与角色可能会有不同的理解,那大家交流起来就会有障碍,怎么办呢?因此,在 DDD 中就出现了“通用语言”和“限界上下文”这两个重要的概念。这两者相辅相成,通用语言定义上下文含义,限界上下文则定义领域边界,以确保每个上下文含义在它特定的边界内都具有唯一的含义,领域模型则存在于这个边界之内。
怎么理解通用语言这个概念呢?在事件风暴过程中,通过团队交流达成共识的,能够简单、清晰、准确描述业务涵义和规则的语言就是通用语言。也就是说,通用语言是团队统一的语言,不管你在团队中承担什么角色,在同一个领域的软件生命周期里都使用统一的语言进行交流。那么,通用语言的价值也就很明了了,它可以解决交流障碍这个问题,使领域专家和开发人员能够协同合作,从而确保业务需求的正确表达。
通用语言包含术语和用例场景,并且能够直接反映在代码中。通用语言中的名词可以给领域对象命名,如商品、订单等,对应实体对象;而动词则表示一个动作或事件,如商品已下单、订单已付款等,对应领域事件或者命令。通用语言贯穿 DDD 的整个设计过程。作为项目团队沟通和协商形成的统一语言,基于它,你就能够开发出可读性更好的代码,将业务需求准确转化为代码设计。
在事件风暴的过程中,领域专家会和设计、开发人员一起建立领域模型,在领域建模的过程中会形成通用的业务术语和用户故事。事件风暴也是一个项目团队统一语言的过程。通过用户故事分析会形成一个个的领域对象,这些领域对象对应领域模型的业务对象,每一个业务对象和领域对象都有通用的名词术语,并且一一映射。微服务代码模型来源于领域模型,每个代码模型的代码对象跟领域对象一一对应。
语言与代码模型映射
根据事件风暴过程领域对象和关系,对产出的限界上下文、聚合、实体、值对象、仓储、事件、应用服务、领域服务等领域对象以及各对象之间的依赖关系进行梳理,确定各对象在分层架构中的位置和依赖关系,建立领域对象分层架构视图,为每个领域对象建立与代码模型对象的一一映射。
根据领域对象在 DDD 分层架构中所在的层、领域类型、与代码对象的映射关系,定义领域对象在微服务代码模型中的包、类和方法名称等,设计微服务工程的代码层级和代码结构,明确各层间的调用关系。
领域对象及服务矩阵主要用来记录事件风暴和微服务设计过程中产出的领域对象属性,如:各领域对象在 DDD 分层架构中的位置、属性、依赖关系以及与代码对象的映射关系等。通过建立领域对象与代码对象的映射关系,可指导软件开发人员准确无误的按照设计文档完成微服务开发。
各栏说明如下:
- 层:定义领域对象位于 DDD 分层架构中的哪一层。如:接口层、应用层、领域层以及基础层等。
- 聚合:在事件风暴过程中将关联紧密的实体和值对象等组合形成聚合。本栏说明聚合名称。
- 领域对象名称:领域模型中领域对象的具体名称。如:“请假审批已通过”是类型为“事件”的领域对象;“请假单”是领域类型为“实体”的领域对象。
- 领域类型:在领域模型中根据 DDD 知识域定义的领域对象的类型,如:限界上下文、聚合、聚合根(实体)、实体、值对象、事件、命令、应用服务、领域服务和仓储服务等。
- 依赖对象名称:根据业务对象依赖或分层调用依赖关系建立的领域对象的依赖关系(如服务调用依赖、关联对象聚合等)。本栏说明领域对象需依赖的其他领域对象,如上层服务在组合和编排过程中对下层服务的调用依赖、实体之间或者实体与值对象在聚合内的依赖等。
- 包名:代码模型中的包名,本栏说明领域对象所在的软件包。
- 类名:代码模型中的类名,本栏说明领域对象的类名。
- 方法名:代码模型中的方法名,本栏说明领域对象实现或操作的方法名。
再来看一个案例,表格中的这些名词术语就是项目团队在事件风暴过程中达成一致、可用于团队内部交流的通用语言。在这个表格里面我们可以看到,DDD 分析过程中所有的领域对象以及它们的属性都被记录下来了,除了 DDD 的领域对象,我们还记录了在微服务设计过程中领域对象所对应的代码对象,并将它们一一映射。
DDD 分析和设计过程中的每一个环节都需要保证限界上下文内术语的统一,在代码模型设计的时侯就要建立领域对象和代码对象的一一映射,从而保证业务模型和代码模型的一致,实现业务语言与代码语言的统一。