jMolecules:Java中DDD模型与架构的抽象库包


这是一组库,可帮助开发人员以无干扰、简单的旧式 Java 实现DDD领域模型。

jMolecules 背后的想法

  • 明确表达架构概念,以便于代码阅读和编写。
  • 使特定领域的代码免受技术依赖。减少样板代码。
  • 自动生成文档并验证实现结构和您的架构。

目标

  1. 让开发人员的生活更轻松。
  2. 表示一段代码(包、类或方法)实现了一个架构概念。
  3. 让人类读者可以轻松地确定给定的代码片段属于哪种架构概念。
  4. 允许工具集成:[list=1]
  5. 代码的增强。 (工具示例:ByteBuddy 与 Spring 和 JPA 集成)。
  6. 检查架构规则。 (工具示例:jQAssistant、ArchUnit)。


用例1:表达 DDD 概念
示例:银行域。

使用基于注释的模型

import org.jmolecules.ddd.annotation.*;

@Entity
class BankAccount {

    @Identity
    final IBAN iban;

    /* ... */

}

@ValueObject
class IBAN {
/* ... */ }

@ValueObject
record Currency {
/* ... */ }

@Repository
class Accounts {
/* ... */ }

当我们认真对待通用语言UL时,我们希望名称(类、方法等)仅包含领域语言中的单词。

这意味着构建块的标题不应成为名称的一部分。

  • 因此,在银行域中,我们不需要 BankAccountEntity、CurrencyVO 甚至 AccountRepository 作为类型。
  • 相反,我们需要的是 BankAccount、Currency 和 Accounts,就像上面的例子一样。

不过,我们还是想表达一个给定的类(或其他架构元素)是一个特殊的构件,即使用了一种设计模式。jMolecules 为 DDD 中已知的构件提供了一套标准注解。

使用基于类型的模型
作为上述注解的替代方案,jMolecules 还提供了一系列接口,这些接口主要基于 John Sullivan 在 "推进企业级 DDD "系列中提出的观点。它们允许在类型系统中直接表达构件之间的关系,这样编译器就能帮助验证模型的正确性,Java 反射也能更轻松地处理这些信息。

  • Identifier (标识符)--一种表示可用作标识符的类型的类型。
  • Identifiable<ID> - 公开标识符的任何东西。
  • Entity<T extends AggregateRoot<T, ?>, ID> extends Identifiable<ID> - 实体,声明它属于哪个 AggregateRoot 以及它暴露了哪个标识符。
  • AggregateRoot<T extends AggregateRoot<T, ID>, ID extends Identifier> extends Entity<T, ID> - 一个聚合根,它是属于自己的实体,并公开一个专用标识符。
  • Association<T extends AggregateRoot<T, ID>, ID extends Identifier> extends Identifiable<ID> - 与目标聚合根的显式关联。

这种安排为建模提供了指导,并可通过反射轻松验证以下规则:

  • 强制执行每个聚合体的专用标识符类型,以避免不同聚合体的标识符混淆。
  • 聚合根(AggregateRoot)必须只引用声明属于它的实体实例。
  • 聚合根和实体只能通过关联实例引用其他聚合根。

有关自动验证和运行时技术集成,请参阅 jMolecules Integrations.。

可用的库

  • jmolecules-ddd — 在代码中表达 DDD 构建块(值对象、实体、聚合根等)的注释和接口。
  • jmolecules-events — 在代码中表达事件概念的注释和接口。
  • kmolecules-ddd — 基于 Kotlin 的风格,jmolecules-ddd以缓解基于类型的模型的 Kotlin/Java 互操作问题。

用例2:表达架构概念
jMolecules 提供注释来描述遵循分层、洋葱和六边形架构风格的更高级别的架构概念。它们允许您将包标记为层、环或包含端口和适配器。

import org.jmolecules.architecture.layered.*;

@DomainLayer
package org.acmebank.domain;

@ApplicationLayer
package org.acmebank.application;

这样,相应软件包中的所有类都被视为注释层、环的一部分,或被视为端口/适配器。

或者,也可以直接对类进行注释:

import org.jmolecules.architecture.layered.*;

@DomainLayer
@Entity
public class BankAccount { /* ... */ }

@ApplicationLayer
@Service
public class TransferMoney {
/* ... */ }

目前,已有分层洋葱和六边形架构 的注释。

可用的库

用例3:生成技术样板代码
jMolecules 注释和接口可用于生成在特定目标技术中表达概念所需的技术代码。

可用的库

用例4:验证和记录架构
以代码表达的 jMolecules 概念可用于验证源自概念定义的规则并生成文档。
可用的库

  • jQAssistant 插件 — 用于验证适用于不同架构风格、DDD 构建块、CQRS 和事件的规则。还可以根据代码库中的可用信息创建 PlantUML 图。
  • ArchUnit 规则 — 允许验证 DDD 构建块之间的关系。
  • Moduliths  — 支持检测 jMolecules 组件、DDD 构建块和事件,以用于模块模型和文档目的(有关更多信息,请参阅博客文章)。

安装:

<dependency>
  <groupId>org.jmolecules</groupId>
  <artifactId>jmolecules-ddd</artifactId>
  <version>1.9.0</version>
</dependency>