模式:在功能退出时做一些优雅的方式?

时间:2010-01-15 19:26:06

标签: design-patterns language-agnostic coding-style

我有一个逻辑函数,如下所示:

doStuff1()
try:
    doStuff2()
except type1:
    error1()
    return endstuff()
except type2:
    error2()
    return endstuff()
except:
    error3()
    return endstuff()

if doStuff3():
    error4()
    return endstuff()

doStuff4()
return endstuff()

如您所见,endstuff()在每个可能的函数退出时完成。就像现在一样,endstuff()实际上是2行代码,我最近不得不在所有可能的退出中添加第三行代码。有没有更优雅的方式来组织这个代码?我不能只使用finally,因为并不总是抛出异常。

7 个答案:

答案 0 :(得分:10)

可以使用终结,即使没有抛出任何异常,AFAIK这是做你想做的最优雅的方式。

答案 1 :(得分:2)

不需要抛出异常来调用finally块。该块的重点是可靠地调用始终。你可以用它。

答案 2 :(得分:1)

无论是否抛出异常,都会执行finally子句,因此您可以将代码包装在try / catch / finally的多个级别中...(这是C#,因为你没有' t指定一种语言)

try
{
    try
    {
         something();
    }
    catch 
    {
         // Err handler for something
    }
}
finally
{
      endstuff();   // this code always runs
}

答案 3 :(得分:1)

根据语言的不同,这是RAII的完美候选人。例如,在堆栈上分配一个对象并在其析构函数中执行“endstuff()”;这样就可以在范围的末尾调用它。

class something
    def ~something()
        darkside()
        endstuff()


// in the function
def somefunc()
    something s

    doStuff1()
    try:
        doStuff2()
    except type1:
        error1()
        return
    except type2:
        error2()
        return
    except:
        error3()
        return

    if doStuff3():
        error4()
        return

    doStuff4()
    return

答案 4 :(得分:1)

我支持finally阻止,但作为替代方案,您可以使用while块,例如:

while(true)
    doStuff1()
    try:
        doStuff2()
    except type1:
        error1()
        break
    except type2:
        error2()
        break
    except:
        error3()
        break

    if doStuff3():
        error4()
        break

    doStuff4()
end while

return endstuff()

如果您使用的语言不支持异常,则此功能非常有用。在这种情况下,你的except type只会检查最后一次返回结果的错误值。

答案 5 :(得分:0)

由于每次都会返回endstuff(),因此您不必将返回呼叫短路。该函数将返回endstuff(),无论发生什么,为什么将代码放在每个检查中?如果有错误,除非你不想做 doStuff4()

更优雅的方法可能是在finally块中执行endstuff()并将该值赋给变量,然后在结尾返回该变量。

答案 6 :(得分:0)

关于'finally'子句的其他注释是正确的,但是当我没有'finally'子句可用时(并非所有语言都可用),我将多退出代码分解为子函数。这不仅适用于try / catch,还有任何代码,您必须检查许多条件并希望避免深层嵌套的'if'子句。此示例显示:

ThingOne() {
    var foo;
    foo.open();

    if (ThingTwo(foo))
        ThingThree(foo);

    foo.close();
}

ThingTwo(var x) { 
    try
    {
        ...normal case...
        return true
    catch x1
        handlex1();
    catch x2
        handlex2();
    }
    return false;
}

ThingThree(var x) {
    if (x.conditionOne == false) return;
    if (x.conditionTwo == true) return;
    ...etc...
    x.GoForIt();
}