【埃尔法哥哥】设计面向DDD的微服务


Domian-driven Design
领域-驱动-设计(DDD)提倡 基于(用例相关的现实业务)进行建模。
【埃尔法哥哥】设计面向DDD的微服务
本文插图
1. DDD的视角
现实问题视为领域
独立的问题描述为有界限的上下文
2. DDD提出的概念
许多技术概念和模式 , 例如充血模型(对应我们常写贫血模型)、值对象、聚合和聚合根规则 。
3. 目前实施DDD的现状
有时DDD技术规则和模式被视为障碍/啰嗦 , 对于实施DDD方法而言 , 学习曲线比较陡峭 。
不要为了实施而实施 , 最重要的是 使用通用语言编写与业务问题一致的领域代码。
此外仅当您要实现具有复杂业务规则的微服务时 , 才应使用DDD方法 , 诸如CRUD服务之类的简单职责可以通过更简单的方法进行管理 。
DDD模式可以协助 划分微服务边界在已经确定的界限上下文 , 您可以为领域建模:实体模型、值对象和聚合 , DDD与边界有关 , 微服务也与边界有关 。
尽量保持小型微服务
划分界限上下文 , 要平衡两个目标:
创建尽可能小的微服务(这一点不应该成为主要动力)
要避免微服务之间过密的通信
这两个目标可能彼此矛盾 , 两者通过演进的方式达到平衡:
尽可能分解系统 , 直到在下次分解时感到服务通信迅速增加 。
【埃尔法哥哥】设计面向DDD的微服务
本文插图
DDD微服务中的层
DDD定义的多层是为了管控代码的复杂性 ,这些层是逻辑组件(类似环环相扣的齿轮) 。
不同的层(例如领域模型层与表示层等)可能具有不同的类型 , 此时层加类型需要转换 。
例如从数据库中加载的实体 , 有时候需要做一下修正(截取部分信息、增加信息)才能适配客户端UI 。
领域模型层中的领域实体不应传播到它不属于的其他区域(如表示层)
重要的是有一个由聚合根控制的域模型 , 以确保与该实体组(聚合)相关的所有不变式和规则都是通过单个入口点或(聚合根)执行 。
【埃尔法哥哥】设计面向DDD的微服务
本文插图
订单DDD微服务有三层:
应用程序层 Ordering.API
领域层 Ordering.Domain
基础设施层 Ordering.Infrastructure
三层形成的类库 有清晰且明确的依赖关系
1. The domain model layer
负责表达业务概念、业务场景和业务规则 。 这一层会将技术细节传递到基础设施层 , 这一层控制、反映业务场景 , 是业务软件的核心 。
领域模型层是表达业务的地方 , 在编程上体现为 捕获数据和行为(具有逻辑方法)的领域实体的类库
遵循 持久性无感知和基础设施无感知 原则
领域模型层必须完全忽略数据持久性细节 , 这些持久性任务应由基础设施层执行 , 因此 , 此层不应直接依赖基础设施 , 这意味着一个重要规则是领域模型实体类应为POCO 。
领域实体不应直接依赖于任何数据访问基础框架(EF、NHibernate) , 理想情况下 , 您的域实体不应继承自或实现任何基础设施中定义的任何类型 。大多数现代的ORM框架(例如Entity Framework Core)都支持这种方法 , 因此您的领域模型不会与基础设施耦合 。
领域模型中遵循 持久性无感知 原则很重要 , 但也不应忽略持久性问题
理解物理数据模型以及它如何映射到您的实体对象模型仍然非常重要 , 否则你的设计将会是空中楼阁 。 而且 , 大多数时候你将本应该采用关系数据库的设计直接迁移到 NoSQL或面向文档的数据库 , 领域模型层很可能不适用(基于存储技术和ORM技术 , 您的实体模型仍然必须遵守一些约束条件) 。


推荐阅读