1

早上好,

比方说,我们有一个定义异常的域,例如ObjectNotFoundException,它需要在域模型中定义的标识符 (VO)。

问题

我们可以直接从请求处理程序中抛出域异常吗,例如:

    class ObjectRequestHandler implements RequestHandler
    {
        ...

        public function __invoke(Request $request, Response $response)
        {
            // Will self-validate and throw an exception if not a valid UUID
            $objectId = ObjectId::fromString(strval($request->param('object_id'])));

            $object = $this->repository->find((string)$objectId);

            if (NULL === $object) {
                // Exception defined at the domain level...
                throw new ObjectNotFoundException($objectId);
            }

            ...
        }
}

这样做也会导致在请求处理程序中使用标识符 VO... 还必须注意,抛出的异常将被默认异常处理程序捕获,而默认异常处理程序将准备并发送JSON响应。

最后,请注意这里的请求处理程序是一个实现细节,而不是问题的一部分。请不要对此发表评论。

谢谢你。

4

1 回答 1

2

您的示例显示了存储库的正确用法,以根据标识符从数据存储中获取对象。

让我们对工作流程进行更多解包和扩展以适应 DDD 的范式,以帮助回答这个问题:

  • API 控制器(或请求处理程序)将使用被调用方发送的请求参数调用应用程序服务。
  • 转发到应用程序服务的请求参数可以是简单数据(如 JSON),也可以是对象(如 DTO)
  • 应用程序服务有权访问与对象关联的正确存储库。
  • 存储库在领域层之外
  • 应用程序服务将使用这些存储库将对象加载到内存中,然后将控制权移交给域层(或调用其中的方法)。
  • ObjectNotFound如果没有找到给定标识符的对象,则通常从存储库中抛出错误
  • 领域层通常从应用程序服务接收它需要处理的所有对象,或者使用工厂方法构建对象。
  • 实际过程就是根据业务规则分配或转换属性值,同时确保满足不变的规则。所以领域层抛出的错误类型是业务规则错误(或验证错误)。

所以,

  • ObjectNotFoundException不是例外
  • 您尚未处于域级别,因此将标识符称为 aValueObject是不正确的

暂时忽略应用程序服务,您在使用该概念时会很准确。代码示例在结构上是正确的。这只是需要澄清的条款。

于 2019-07-21T17:01:08.380 回答