gpt4 book ai didi

CQRS 命令和事件作为通用类?

转载 作者:行者123 更新时间:2023-12-01 09:54:28 24 4
gpt4 key购买 nike

在我看到的大多数示例中,命令和事件都表示为类。这意味着您必须编写一个带有 name 属性的 CorrectNameCommand 类和一个带有 name 属性的 NameCorrectedEvent 类。鉴于在大多数情况下命令和事件都被序列化和反序列化并发送给其他方(编译时类型安全),与更通用的类相比,这种显式类有什么优势?

示例:

一个带有名称的命令类(表示命令的类型)、应该处理命令的 ag 的键以及任何其他参数的对象数组或名称/值对。

一个 Event 类本质上是一样的(也许我们可以把共享的部分放在一个 CommandEventBase 类中)。

命令(和事件)处理程序现在必须检查命令(事件)的名称而不是其类类型,并且必须依赖列表中参数的正确性(就像反序列化器必须依赖序列化格式正确)。

这是一个好方法吗?如果是,为什么在示例和教程中不使用它?如果不是,问题是什么?

最佳答案

复制

当命令和事件被序列化时,编译时的安全性丢失了,这是一个公平的观点,但在静态类型语言中,我仍然更喜欢强类型的命令和事件类型。

这样做的原因是它为您提供了一个负责解释消息元素的代码库。序列化往往是相当(类型)安全的;反序列化是您可能会遇到问题的地方。

不过,我更愿意在一个地方处理任何此类问题,而不是分散在整个代码库中。

这与事件特别相关,因为您可能有多个事件处理程序处理相同类型的事件。如果您将事件视为弱类型字典,则需要 重复 Tolerant Reader的实现在每个事件处理程序中。

另一方面,如果您将事件和命令视为强类型,则您的反序列化器可能是您必须维护的单个 Tolerant Reader。

类型

综上所述,我可以理解为什么您在使用 C# 或 Java 等语言时会发现为每条消息定义不可变的 DTO 似乎有很多开销:

public sealed class CorrectNameCommand
{
private readonly string userId;
private readonly string newName;

public CorrectNameCommand(string userId, string newName)
{
this.userId = userId;
this.newName = newName;
}

public string UserId
{
get { return this.userId; }
}

public string NewName
{
get { return this.newName; }
}

public override bool Equals(object obj)
{
var other = obj as UserName;
if (other == null)
return base.Equals(obj);

return object.Equals(this.userId, other.userId)
&& object.Equals(this.newName, other.newName);
}

public override int GetHashCode()
{
return this.userId.GetHashCode() ^ this.newName.GetHashCode();
}
}

确实, 似乎有很多工作 .

这就是我现在更喜欢其他语言来实现 CQRS 的原因。在 .NET 上,F# 非常适合,因为 以上所有代码都归结为这一行 :
type CorrectNameCommand = { UserId : string; NewName : string }

这就是我要做的,而不是传递弱类型字典。上次我听到 Greg Young 谈论 CQRS(NDC Oslo 2015)时,他似乎也“转换”到了 F#。

关于CQRS 命令和事件作为通用类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31139227/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com