如何使用 DTO 处理与命令总线方法的关系

How to handle relationships with a command bus approach using DTO's

在一个新的新建项目中,我正在使用命令总线方法,我遇到的问题是我应该如何处理关系。

例如,一个订单有多个订单行、一个送货地址和发票地址。

因为我使用的是命令总线方法,所以我想将 DTO 传递到我的命令总线,其中包含创建订单所需的所有信息。

此命令是否也应保持关系(即 CreateOrderTask、CreateOrderAddress)?

我的 directory/file 结构如下所示:

- Infrastructure
-- Ui
--- Web
---- CreateOrderController.php
-- ....
- Application
-- CreateOrder
--- CreateOrder.php
--- CreateOrderHandler.php
--- CreateOrderLine.php (?)
- Domain
-- Order
--- Order.php
--- OrderLine.php
--- Address.php
-- ...

那么 CreateOrder class 应该是这样的:

// CreateOrder.php

<?php

class CreateOrder {

    /** @var CreateOrderLine[] */
    protected $createOrderLines;

    public function __construct(array $createOrderLines) 
    {
        $this->createOrderLines = $createOrderLines;
    }

    public function getCreateOrderLines()
    {
        return $this->createOrderLines;
    }
}

虽然我认为有很多正确答案,但我正在寻找最佳实践。你有什么想法?

这取决于您的交易边界。

如果您需要所有命令必须一起成功或一起失败那么您实际上必须有一个包含所有数据的更大命令需要。

如果任何子命令失败并且系统仍处于有效状态,那么您不需要更大的命令,您可以以某种批处理方式发送多个命令,每个命令都有自己的事务边界。

电子商务是一个非常流行的领域,在这里可能更有趣的是查看您的系统行为的业务内容。

稍微远离 CQRS,我会问你一些 "DDD-style" 个问题:

  • 订单从哪里来?
  • CreateOrder 是什么意思?谁创造了它们?
  • 购物车呢?不是一行一行填的吗?
  • 您的企业不需要了解中止的购物车吗?

我会警告您不要过度简化相关域并过度设计解决方案...

如果您在一天结束时会有一个购物车 - 您可能有向其中添加商品的命令。这些命令将异步发出。不会有 AddShoppingCartHeader 命令,因为它对业务没有任何意义。结帐时,购物车可能会转换为订单。或者,在超时后,它将被丢弃并创建一个线索。如果这一切都有效 - 您可能想要查看流程管理器模式(在许多消息传递框架中也称为 Saga)。