【问题标题】:Dealing with non-trivial command and event payloads in Axon在 Axon 中处理重要的命令和事件有效负载
【发布时间】:2017-06-07 22:44:16
【问题描述】:

每当我查看Axon Bank 时,我都会开始思考是否应该遵循一组事件和命令的设计规则。

在 Axon Bank 中,事件和命令都完全由原语组成。在我的应用程序中,我倾向于尽可能避免使用原始用法,主要是为了构建一个富有表现力的域并在我能获得的任何地方保持类型安全。

Axon 本身带有一些 DDD 引用,但无论我浏览哪些文档,没有一个示例使用复合对象作为事件/命令负载的一部分。

这让我很困惑。内置对完整的 xml 和 json 序列化的支持,不仅可以拥有一些键值对。

我知道,特别是事件往往是小而简单的结构,因为它们只反映增量状态变化,但复杂的域模型和事件(条目)之间总会存在某种差距。


在我的域中,我可以拥有一堆类,例如 OverdraftLimit、CurrentBalance、Deposit 和 AccountIdentifier。

现在有两种可能的方式来设计事件和命令:

1。基元和广泛的转换

  • 将事件视为带有漂亮标签的原始数据
  • 在原始数据“进入”应用程序后立即将其转换为强大的对象
  • 创建事件时,只需将它们再次剥离即可。

    public class BankAccountcreatedEvent {
        private final String accountIdentifier;
        private final int overdraftLimt;
    
        // ...
    }
    

    还有其他地方:

    public void on (BankAccountCreatedEvent event) {
        this.accountIdentifier = AccountIentifier.fromString(event.getAccountIdentifier());
        this.overdraftLimit = new OverdraftLimit(event.getOverdraftLimit());
    }
    

优点:

  • 简单的命令/事件 API,没有任何奇怪的依赖关系
  • 使分发更容易
  • 只有在实际事件结构发生变化时才需要上调者,因此可以轻松预测。

缺点:

  • 需要编写和维护一个巨大的转换层
  • 主要出于技术原因将事件/命令与域模型的其余部分解耦会引入新的、人为的上下文差距

2。富有表现力的负载

  • 直接使用复杂的类型作为属性

    public class BankAccountCreatedEvent {
        private final BankAccountIdentifier bankAccountIdentifier;
        private final OverdraftLimit overdraftLimit;
    
        //..
    }
    

优点:

  • 写得更少,读起来更容易
  • 自然而然地保持在一起

缺点:

  • 领域逻辑会间接影响事件结构,因此需要更频繁地进行向上转换,并且更难以预测。

我需要第二个意见。有推荐的方法吗?

【问题讨论】:

    标签: java spring axon


    【解决方案1】:

    首先要记住的是,事件的序列化形式是您的正式合同。最后,如何在 Java 类中表示这一点取决于每个应用程序。例如,如果您将序列化程序配置为忽略未知字段,则可以将不关心的字段留在外面。

    就我个人而言,我不介意事件中的原语。但是,我确实理解对某些字段使用显式值对象的价值,因为它们允许您表达每个字段所涉及的“数学”。在标识符的情况下,它们可以防止“混淆”,在这种情况下,标识符被用于意外地尝试识别另一种类型的对象。

    最后,这并不重要。通过一些简单的 Jackson 注释,您可以将这些值对象转换为 JSON 中的简单值。例如,查看@JsonValue。

    public class BankAccountCreatedEvent {
        private final BankAccountIdentifier bankAccountIdentifier;
        private final OverdraftLimit overdraftLimit;
    
        //..
    }
    

    将映射到:

    {
        "bankAccountIdentifier": "abcdef1234",
        "overdraftLimit" : 1000
    }
    

    如果 BankAccountIdentifier 和 OverdraftLimit 类都有一个 @JsonValue 注释方法,该方法将返回它们的“简单”值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-18
      • 1970-01-01
      • 2018-07-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多