php - EventSourcing, Aggregates – 使用不变量而不加倍它们
问题描述
我在我的应用程序中非常基本地使用事件溯源技术,但是我遇到了一个概念问题。让我们直接举个例子。
ProductAggregateRoot.php
public function changePrice(ChangeProductPrice $command): self
{
if ($this->availability->equals(Availability::UNAVAILABLE())) {
throw CannotChangePriceException::unavailableProduct();
}
if ($this->price->equals($command->newPrice)) {
throw CannotChangePriceException::priceHasntChanged();
}
$this->recordThat(
new ProductPriceChanged($this->price, $command->newPrice)
);
return $this;
}
现在,我想创建一些其他方法(甚至域服务,并不重要),这很简单:
- 从外部来源获取当前价格和可用性
- 尝试更新总价。
- 尝试更新总体可用性。
如您所见,在更新价格时,我正在检查一些业务不变性,例如如果产品不可用,您无法更改价格,如果其价值没有改变,您无法更改价格。如果任何不变量被破坏,则抛出异常。
现在,在我的域服务中,我想根据外部数据源更改价格和可用性。现在,我只是做了一些 try catch 块,如下所示:
try {
$aggregate->changePrice(new ChangeProductPrice(
$productId,
$state->getPrice()
));
} catch (CannotChangePriceException $ex) {
}
一个用于价格的 try-catch 块,另一个用于可用性等。它有效,但我觉得它完全是错误的和hacky。我会对简单的 if 块和方法/规范(如CanChangePrice()
. 但是,我需要双重使用它——无论是在服务中还是在具体方法本身,这听起来也不好。
问题是:你们如何处理这些事情?这似乎是一个非常微不足道的问题,但我仍然没有找到让我感觉良好的解决方案。
解决方案
几个想法:
为什么没有“更改价格和可用性”命令?这更好地捕捉了更新两者的意图,并允许不变检查具有更好的上下文知识(例如,如果我们将可用性更新为可用,那么当前可用性是没有意义的,因为它是先前时间的遗物)。
我有点怀疑将价格更改为实际当前价格的尝试是错误的。在我看来,这个命令是表达一种将价格变成期望价格的愿望,所以如果这个愿望已经得到满足,为什么还要犯这个错误呢?返回
$this
(实际上是耸耸肩并说“确定”)似乎更好,并且不会强迫请求者知道当前价格(严格来说,他们不能知道当前价格)。
推荐阅读
- c# - 可以做些什么来防止此 MailKit SMTP 失败?
- reactjs - reactjs中未从父级调用子组件函数
- c++ - C++ 对编译的多重定义
- tensorflow - tensorflow(lambda 文本,标签:文本)仅文本并使用 pyspark 进行调整
- bash - npm 不会安装 sass 并且无法输入密码
- c# - azure 函数应用程序中的 LINQ 子查询返回错误消息
- sql-server - 外部应用内的 WITH 语句
- node.js - 如何从文件夹中删除已添加的 developer-pop?
- java - 在 jar 中获取代码以运行,而无需在 Tomcat 中显式调用
- keycloak - 细粒度权限 - 管理员 (v13.0.1)