在哪里进行外部聚合验证?

时间:2017-06-29 15:58:32

标签: domain-driven-design

我有一个关于外部聚合验证的问题。

  • 在我们的域名合作伙伴中,可以下达包含特定产品的订单(1)。
  • 一旦下订单(2),他可以在我们的系统中将其标记为已付款(3)。
  • 一旦订单被标记为已付款(4),我们就会将许可证分配给外部图书馆服务(5)中的产品。
  • 一旦我们知道许可证被分配(6),我们就会关闭整个传奇。

这是一张说明这个过程的小图:

enter image description here

此时除命令,命令处理程序和事件外,还有两个涉及整个过程的域类:

包含业务逻辑的订单聚合 订购传奇协调整个流程并分配许可证

现在,有一个未在此过程中建模的不变量 - 在我们将订单标记为已付款之前,我们必须检查用户是否尚未分配特定许可证。我们也从图书馆服务中得到这个。

你会在哪里进行验证?命令处理程序在某些域名服务中包含订单?将一些验证器传递给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
    }
}

1 个答案:

答案 0 :(得分:0)

据我所知,问题出在第3步(将订单标记为付款)。在这一步中,我们需要一个用户(让我们称之为付款人)将订单标记为付款。因此,在创建此付款人对象(可能使用工厂)时,我们需要知道他是否被允许将订单标记为已付款。为了获得这些信息,应该调用外部库。

我的建议是拥有->markOrderAsPayed($orderId, $payerUserId)的应用服务 此方法将调用2个域服务。一个用于获取付款人,一个用于将订单标记为已付款。

$payer = $this->payerService->getPayer($payerUserId);
$this->orderService->payOrder($orderId, $payer);

getPayer()功能中,您应该拨打外部资料库,了解付款人拥有的许可证数量。

我希望这会有所帮助,它只是基于我从问题和评论中理解的内容。