【发布时间】:2017-12-03 10:37:13
【问题描述】:
我有一个关于外部聚合验证的问题。
- 在我们的域合作伙伴可以下订单包含某些产品 (1)。
- 下单后 (2) 他可以在我们的系统中将其标记为已付款 (3)。
- 一旦订单被标记为已付款 (4),我们就会为外部库服务中的产品分配许可证 (5)。
- 一旦我们知道分配了许可证 (6),我们就会关闭整个 saga。
这里有一张小图来说明这个过程:
此时除了命令、命令处理程序和事件之外,整个过程还涉及两个领域类:
包含业务逻辑的订单聚合 订单传奇协调整个流程并分配许可证
现在,有一个不变量尚未在此过程中建模 - 在我们将订单标记为已付款之前,我们必须检查用户是否尚未分配特定的许可证。我们也从图书馆服务中得到这个。
你会把这个验证放在哪里?命令处理程序?在某些域服务中包装订单?将一些验证器传递给 Order 构造函数?
class Order
{
public function __construct(OrderValidator $validator)
{
if (!$validator->isValid($this)) {
throw new \DomainException();
}
// else proceed
}
}
class OrderValidator
{
private $libraryServiceClient;
public function isValid(Order $order)
{
// check licence using $libraryServiceClient
}
}
【问题讨论】:
-
如果你想要一个严格的验证,你可以传递一个“服务”,在执行 MarkPaid 命令的聚合方法中进行验证,并在更改状态之前检查它
-
我认为用户应该是模型的一部分,因为每个订单都有一个创建它的用户。然后验证可以很简单并且仍然在聚合的一侧。用户类可以只有一个方法 ->isAllowedToMakePayment() 或 ->hasLicence()
-
@MohamedBouallegue 当然,但许可证检查实际上是不同有界上下文的一部分,所以它必须委托给某个地方 - 我的问题是如何。