My favorite is a variant of alternative 2.
{
...
DoInit();
status=DoAllActions();
DoCleanup(status);
...
}
int DoAllActions()
{
if (condition1_fails)
return status1;
...
if (condition2_fails)
return status2;
...
if(conditionN_fails)
return statusN;
PerformActionOnAllSuccess();
return statusSUCCESS;
}
DoCleanup(status)
{
if(status==statusSUCCESS)
DoNormalCleanup();
else
DoFailedCleanup();
}
Avoiding retuns or additional functions, I would write the following code:
{
if(condition1_fails)
status=status1;
else if(condition2_fails)
status=status2;
...
else if(conditionN_fails)
status=statusN;
else
{
PerformActionOnAllSuccess();
status=statusSUCCESS;
}
if(status==statusSUCCESS)
DoNormalCleanup();
else
DoFailedCleanup();
}
This form of "
else if
" is like a
case
-statement, but much more flexible because you can replace
ConditionN
by a function-call instead of testing only one value. This untypical arranging of
if
and
else
makes clear what the programmer wanted. But often, you have to do a lot of work between the tests which cannot be put into a single function so the first variant is the best and most flexible, I think.