聚合根用于控制状态变化 - 当前允许的内容和不允许的内容。如果允许状态转换,请继续。如果没有,你会抛出一个异常,解释为什么不允许它。
但是,如果 state- 更改没有发生,那是因为 已经处于请求状态 ?
例如,如果您在聚合根上有Approve
方法,并且在调用它时,状态已经被批准了吗?
在我的情况下,我使用事件源,因此如果发生状态更改,则会发出事件。在我的事件流中没有真正状态改变的事件对我来说并不“干净”,因为我希望确信这些事件实际上是由于状态改变的行为而产生的。
有经验法则吗?
修改
在所描述的情况下,批准批准的元素不会真正受到伤害。所以倾向于这种方式(谢谢@Eben Roux,@ guillaume31)。
但是让我们再添加一些 spice (问题背后的实际问题):
假设:
如果进程管理器(也称为saga)发出命令(异步)并想知道命令是否成功,该怎么办?我认为如果流程管理员不必关心关于此实现细节,它将减少心理负载/错误源。
我看到有三种处理方法:
ApprovalDeclined { WasAlreadyApproved = true }
我知道:“这取决于” 但你能想到任何其他(更优雅/更容易/不同)的解决方案吗?您最喜欢的“流程管理器兼容”方式是什么?
答案 0 :(得分:2)
我不认为这会有一个经验法则。
消息幂等当然是一件好事,所以简单地忽略消息/状态改变可能是的方式。
我不会再发出信号,因为没有效果。
答案 1 :(得分:1)
我会说这取决于你的域名。如果您想警告用户他们正在批准已经批准的东西,则必须从汇总中获得一些反馈。它可以是异常as in Deactivate()
here,也可以是应用程序服务/命令处理程序中继的返回值(请注意,这可能不符合100%CQRS)。
如果已经批准的事实对于域任务并不重要,那么无论如何都可以忽略该操作或再次执行该操作。
从用户界面的角度来看,您很可能不会允许重新批准某些内容,因此发生这种情况的情况将是微不足道的:2个用户的并发批准,执行“强力”批准的脚本等。
答案 2 :(得分:0)
对我而言,似乎让您对应用程序和基础架构级别的问题感到困惑。
应用程序级别与预期的域特定行为有关。批准两次的商业理由是什么?为什么甚至会发生这种情况?也许它只是一个UI级别的并发性事物,但是,为什么多个用户在同一时间批准相同的事情呢?也许在业务层面存在一个尚未解决的问题。理解为什么首先是必不可少的。解决方案通常不在软件本身中。
基础设施级别涉及诸如保证消息传递之类的事情(例如,至少一次或恰好一次)。当基础设施无法兑现承诺时,这对业务有何影响(如果有的话)?它如何影响您的流程?无论如何,你的过程是什么?同样,从域特定的角度来理解这些事情是至关重要的。在一天结束时,您可以进行风险或运营成本缓解。
在这种特殊情况下,问问自己为什么以及如何在启动批准命令之前将进程放在原处(对于批准过程有点奇怪,它通常由人类完成)。为什么它没有观察到之前的批准(请记住,什么是聚合已经批准)?你可以引入一个超时(作为一个消息给它(过程)未来的自我)但在这种情况下这样做似乎有点奇怪(我不知道差不多可以告诉你)。
不要采取错误的方式,但我认为您需要深入挖掘特定领域的一面或分享更多细节。