将常见异常抛出逻辑提取到自己的方法中是一种好习惯吗?

时间:2015-01-13 17:22:33

标签: c# .net exception design-patterns

我们在代码库中重复了以下内容:

var isUpdateAllowed = await this.security.IsUpdateAllowedAsync(userId, postId);
if (!isUpdateAllowed)
{
    throw new UnauthorizedException(string.Format(
        "Not allowed to update post. User={0} Post={1}",
        userId,
        postId));
}

我们已经必须更改一次异常类型,这涉及到在很多地方更改它,所以看起来重复上述操作违反了DRY。

一个建议的解决方案是我们将上面的检查提取到它自己的方法中。它可以与现有的IsUpdateAllowedAsync方法一起存在。我们可以称之为AssertUpdateAllowedAsync。然后呼叫站点变为:

await this.security.AssertUpdateAllowedAsync(userId, postId);

我亲身撕裂:一方面我们得到了干,但另一方面我记得在MSTest中使用上述约定的许多方法,而不是Assert.

3 个答案:

答案 0 :(得分:0)

每当你发现自己复制代码时,将它放入帮助方法是一种很好的做法。最重要的原因是你已经看过 - 当代码只需要在一个地方而不是很多地方进行更改时,重构会变得更顺畅。

您经常看到Assert方法的原因是因为抛出异常通常是作为方法的一部分完成的,检查以获取权限等可访问性是通过{{1}完成的 - 返回检查方法。这是因为由于收集了可能有用的调试信息(例如当前bool)而抛出异常是昂贵的 - 因此在生产代码中通常不希望抛出异常而不是实际的,诚实的和确认的错误发生,即便如此,它主要是告诉你要回去修理什么。

答案 1 :(得分:0)

是的,这是一个好主意。

抛出异常的代码与重用的任何其他代码没有什么不同,在这种情况下它肯定是合理的。

如果您不喜欢该名称,那么ThrowIfUpdateNotAllowedAsyncCheckUpdateAllowedAsync如何,虽然我更喜欢您已选择的名称。

将这种逻辑重构为方法的最大批评是你正在使用控制流的异常 - 而重构为一个单独的方法是一个简单,直截了当的方向,我可能会看看我是否可以重构以避免完全抛出这个异常。

答案 2 :(得分:-1)

当然这样做很好。 但是,我想补充一下,不要让你的assert方法异步。这没有意义。