一个用于创建采用菱形架构和领域驱动设计的项目的迷你框架

v4.2.0 2023-07-06 11:44 UTC

README

一个小型框架,用于通过事件源(ES)+ 领域驱动设计(DDD)+ CQRS(命令查询责任分离)架构开发应用程序,侧重于编写部分。

1. 理论

以下将解释如何使用此框架设计应用程序的基本概念,这些原则是推荐的,但不是强制性的。

1.1 菱形架构

应用程序设计应遵循菱形架构的建议,通过三个主要层次,应用程序、领域和基础设施,以及两个辅助层次,用于实用程序和接入点。

├─ Application
├─ Domain
├─ Infrastructure
├─ EntryPoint
└─ Util

设计将分布在以下部分:

  • Application 包含命令和处理器,其目的是将外部请求转换为对领域层的请求。
  • Domain 包含业务逻辑,分布在模型和领域服务中。
  • Infrastructure 包含在特定技术或服务中实现的领域层依赖项的实施,例如,例如,存储库(用于 mongo、mysql、postgresql 等)。
  • Util 包含通用实用程序,可能在任何层中使用。
  • EntryPoint 包含应用程序服务的所有接入点,例如控制台命令和用于 API HTTP 请求的控制器等。

规范如下:

  • EntryPoint 使用依赖注入资源(如依赖注入容器)来处理依赖注入问题,它负责将基础设施实例注入到领域服务中;然后,这些服务再注入到应用程序中。
  • EntryPoint 只能使用应用程序层的类。
  • Application 只能使用领域层的类。
  • Domain 完全独立,并且不知道(除了实用程序)任何外部内容。

此迷你框架中提供的一些工具有助于解决这些问题。

1.2 事件源

领域层由可变且丰富的模型(或实体)组成,具有将它们持久化到特定模型表的 CRUD 请求的存储库服务和接口。事件源更进一步,将业务领域发生的所有事件持久化到单个表中。模型将执行这些事件序列。

此模型通常称为根聚合,可能由其他小型模型组成,称为聚合,这些聚合不能独立于根聚合进行管理。对模型执行的所有操作都会生成一个事件。想法是反转此过程,并使事件本身执行对模型的操作。

1.3 异步:写入与读取

持久化的事件不是对业务数据进行读取操作的高效方式,因此这种架构几乎强制从一开始就实现 CQRS。建议将写入系统与读取系统完全分开;这两个系统之间的通信完全基于异步消息队列。

总的来说,书写系统通过读取持久化的事件来加载其模型,并且其操作将持久化并将新事件发布到一个消息队列系统(例如rabbitMQ)。异步地,读取系统的作业(cron或worker)将消费这些事件,目的是生成和持久化自己的读取模型,也称为投影。这些投影通常存储在面向复杂搜索的数据库中,如mongo或elastic search。

从事件发布开始,到投影应用事件为止,会有一段时间间隔,在这个时间内,读取系统会有数据不同步。这个问题被称为最终一致性,程序员的许多任务之一就是将这个时间间隔减到最小,并在设计解决方案时自觉地管理这种不可避免的特殊情况。

可能还有一点很有趣,书写系统也有自己的事件队列消费者,以便解耦任务并生成将异步执行的命令。这一切都取决于你如何设计你的应用程序。

这个库没有提供针对读取系统的有意义的工具。

2. 开始

这是一篇小教程,旨在逐步了解这个库的各个组成部分。

---待完成---