再谈领域驱动设计( 二 )


通过界限上下文人为将问题子域限制在有限的界限内,你才可以着手创建解决方案 。

再谈领域驱动设计

文章插图
 
创建统一语言团队之间共享的术语和词汇被称为统一语言 。统一语言用来定义业务领域的共享模型,当然可以用在项目的任何地方,包括需求分析和设计,最重要的是统一语言还需要出现在代码中 。另外,统一语言在不同的界限上下文中往往不能够通用,例如在“认证上下文”中提到“用户”,在“机票订单上下文”中叫做“乘客” 。
领域建模有了界限上下文,让解决方案聚焦在最有用的信息里,你才可以着手建立共享模型 。
如何才能建立一个不错的共享模型呢?
使用可视化的图示似乎是一个不错的想法,但实际上画出一个能够表达所有领域知识的图示并不是一个简单的工作;如果你有数据库开发相关的经验,你可能会想到通过表和主外键来表达领域知识,如果你有这样的想法那你就错了,在领域驱动设计中讲究通过领域逻辑来驱动设计和开发工作,而不是通过数据库模型来驱动开发 。
在领域驱动设计中这一步叫做”领域建模“,你应该用代码建立一个反映领域知识的模型,这个模型跟领域专家口中的领域知识是一致的 。领域模型是提供业务能力的核心部件,也是整个应用程序提供业务能力的核心 。
再谈领域驱动设计

文章插图
 
领域建模中的其他概念对于开发者而言领域建模至关重要,也是最考验开发者功底的一个环节 。一方面开发者需要抽象出一个跟领域专家口中一致的模型,另一方面开发者还需要通过代码将这个模型表达出来 。你需要恰如其分的使用一些面向对象的技巧把领域知识抽象到一个代码模型中,在这个过程中你需要了解”值对象”,”实体“,”聚合根“等概念,在此不再细说 。
领域模型的持久化在领域建模以及之前的步骤中,我们都没有提及数据库,因为领域驱动设计的核心是用代码建立一个共享模型,而数据库设计根本就不是领域驱动设计关心的内容 。
但是终究我们还是要把领域模型的状态持久化到数据库中,有没有办法在不关心数据库表结构的情况下,将已经建立好的领域模型持久化?主流ORM的Code First恰好匹配我们现在的处境,已经有一点为领域驱动设计而生的味道了 。
但是即便是ORM的Code First也会对领域模型有侵入,你可能需要根据不同的ORM为模型加上一些注解或者配置之类的代码,这跟领域驱动设计其实是相互违背的,我们希望用代码创建一个纯净的领域模型,这个模型封装着领域专家的领域知识,除此之外的代码都跟领域模型是无关 。
领域事件及事件溯源解决上面问题的思路是引入领域事件和事件溯源 。领域模型在提供业务能力的过程,就是领域模型状态发生变化的过程 。一旦领域模型的状态发生了变化,就会产生一个事件,这跟事件风暴中提到的业务事件是一致的,例如”用户已下单“ 。订单模型在提供”用户已下单“的业务能力后发生了状态变化 。事件溯源的思路就是只持久化领域事件,然后通过还原事件的方式将领域模型还原在最新的状态 。
通过采取事件溯源,就可以将领域模型持久化跟数据库完全解耦 。
再谈领域驱动设计

文章插图
 
微服务和领域驱动设计我们通过领域驱动设计的思路来分析和发现问题域,通过分解把问题域划分为问题子域,通过人为加限制的方式将问题子域转换为限界上下文 。而这个过程就是我们分解微服务的过程,一般来说每一个限界上下文都可以映射为一个微服务,但也不是绝对的,具体情况具体分析 。
再谈领域驱动设计

文章插图
 
微服务的交互和集成每一个微服务专注于解决对应的限界上下文中的问题,并不代表微服务之间没有交流 。单个微服务的领域模型在提供服务的过程中会产生领域事件,领域事件为基于事件驱动(Event based)的微服务集成提供了基础,如果在微服务之间架设一条消息总线(不同于ESB,ESB被认为是反模式) 。不同的微服务将自己产生的领域事件广播在消息总线上,微服务之间通过订阅自己感兴趣的事件就能完成微服务的集成 。
再谈领域驱动设计


推荐阅读