【问题标题】:Is a "guard" method throwing an exception good practice?抛出异常的“守卫”方法是一种好习惯吗?
【发布时间】:2018-02-14 23:46:49
【问题描述】:

以下代码是否会被视为“良好”做法?

它是包的 RPC 端点的控制器。 这个想法是轻松覆盖/扩展包含该包的特定项目的验证或授权。

你能说这些是保护条款或方法吗? 拥有一个仅用于检查某些内容并在出现问题时抛出异常的方法是一个好主意吗?

代码对我来说看起来很干净,但我想就此获得一些建议:)

public function doSomethingWithCustomer() {
    try {
        $this->validate();
        $this->authorize();
        $customer = $this->resolveCustomer();
        $customer->doSomething();
    } catch (HttpException $e) {
        $this->logger->error($e->getMessage());
        return $this->errorResponse($e->getStatusCode(), $e->getMessage());
    }
}

protected function validate()
{
    // Validate input

    if (!$valid) {
        throw new BadRequestHttpException('Invalid email address');
    }
}

protected function authorize()
{
    // Do some authorization checking

    if ($notAuthorized) {
        throw new AccessDeniedHttpException('Not authorized');
    }
}

protected function resolveCustomer()
{
    $customer = Customer::load(1);

    if (is_null($customer) {
        throw new NotFoundHttpException('Customer not found');
    }

    return $customer;
}

【问题讨论】:

  • 这种事情在整个 JDK 中都可以看到,例如在 SocketSocketImpl 之间,或者在许多方法中,在完成所有明显的检查后最终委托给 JNI。
  • 基本上这是例外的目的。在出现问题时短路正常流量。虽然我会将授权检查移动到不同的类并在必要时覆盖它。

标签: design-patterns exception-handling guard-clause


【解决方案1】:

不,这是一种不好的做法,原因如下:

  1. 您永远不应捕获保护子句异常(它是快速失败方法的一部分)
  2. 方法不能只包含保护子句
  3. 保护子句不应验证业务逻辑

Here 是我的一篇关于保护条款的文章。我希望它能帮助你更好地理解它们。

【讨论】:

  • 我不确定这是不是真的......例如,请参阅 Apple 关于 JSON 的文档,此处:developer.apple.com/swift/blog/?id=37
  • 我的意思是当你知道以后会捕获它时抛出异常是错误的。从保护子句中抛出是非常好的,但你不应该抓住保护子句异常。无论是模式还是选项模式都是更好的选择。
  • 知道了,第一次没看懂
猜你喜欢
  • 2012-08-22
  • 1970-01-01
  • 2015-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-22
  • 1970-01-01
  • 2015-09-02
相关资源
最近更新 更多