错误处理的设计模式

lox*_*dog 2 c# asp.net error-handling design-patterns custom-error-handling

我在各个项目中遇到过这个问题几次,我想知道是否有比我通常最终使用的解决方案更好的解决方案.

假设我们有一系列需要执行的方法,并且我们想知道其中一个方法中是否出现问题并优雅地突破(可能撤消任何先前的更改......),我通常会执行以下操作(伪C#,因为这是我最熟悉的):

private bool SomeMethod()
{
    bool success = true;
    string errorMessage = null;
    success = TestPartA(ref errorMessage);
    if (success)
    {
        success = TestPartB(ref errorMessage);
    }
    if (success)
    {
        success = TestPartC(ref errorMessage);
    }
    if (success)
    {
        success = TestPartD(ref errorMessage);
    }
        //... some further tests: display the error message somehow, then:
        return success;
}

private bool TestPartA(ref string errorMessage)
{
    // Do some testing...
    if (somethingBadHappens)
    {
       errorMessage = "The error that happens";
       return false;
    }
    return true;
}
Run Code Online (Sandbox Code Playgroud)

我只是想知道(这是我的问题),如果有更好的方法来应对这种事情.我似乎最终写了很多if陈述,看起来应该更流畅.

我被建议在一组委托函数上进行循环,但是我担心这会过度设计解决方案,除非有一个干净的方法来完成它.

Pol*_*fun 6

我认为你应该使用例外.请注意,通常只应在应用程序的"顶层"捕获异常.

private void TopLevelMethod()
{
    try
    {
        SomeMethod();
    }
    catch (Exception ex)
    {
        // Log/report exception/display to user etc.
    }
}

private void SomeMethod()
{
    TestPartA();
    TestPartB();
    TestPartC();
    TestPartD();
}

private void TestPartA()
{
    // Do some testing...
    try
    {
        if (somethingBadHappens)
        {
            throw new Exception("The error that happens");
        }
    }
    catch (Exception)
    {
        // Cleanup here. If no cleanup is possible, 
        // do not catch the exception here, i.e., 
        // try...catch would not be necessary in this method.

        // Re-throw the original exception.
        throw;
    }
}

private void TestPartB()
{
    // No need for try...catch because we can't do any cleanup for this method.
    if (somethingBadHappens)
    {
        throw new Exception("The error that happens");
    }
}
Run Code Online (Sandbox Code Playgroud)

我在我的例子中使用了内置的System.Exception类; 您可以创建自己的派生异常类,也可以使用从System.Exception派生的内置类.


Gar*_*ery 5

您也许可以尝试查看SOLID 原则的“开/闭”部分。在您的示例中,您也许可以创建一个ITestRule接口,其中包含一个调用的方法CheckRule(),该方法将更新您的消息并返回bool. 然后,您将为要测试的每个规则创建一个接口实现,并将该类添加到对象中List<ITestRule>。从上面的 Redmondo 示例中,我将更改为以下内容:

var discountRules =
                new List<ITestRule>
                    {
                        new TestPartA(),
                        new TestPartB(),
                        new TestPartC(),
                        new TestPartD(),
                    };
Run Code Online (Sandbox Code Playgroud)

然后,您将 new 传递List<ITestRule>给评估器,该评估器将循环遍历每个类并运行该CheckRule()方法。