notCondition2And3 = !condition2 & !condition3;
// in place of notCondition2And3 should be some meaningful name
// representing what it actually MEANS that neither condition2 nor condition3 were true
And now:
if (condition1 || notCondition2And3)
{
Statement1A;
Statement1B;
return;
}
if (condition2)
{
Statement2;
return;
}
if (condition3)
{
Statement3;
return;
}
As I wrote in my comment to Kieveli's answer, I see nothing wrong about multiple return
s in a method, if there is no memory management considerations (as it might be the case in C or C++ where you have to release all resources manually before you leave).
Or another approach still. Here's the decision matrix so that we don't mess it up:
F F F - 1
---------
F F T - 3
---------
F T F - 2
F T T - 2
---------
T F F - 1
T F T - 1
T T F - 1
T T T - 1
T
s and F
s represent the values of condition1
, condition2
and condition3
(respectively). The numbers represent the outcomes.
It makes it clear that it's also possible to write the code as:
if (!condition1 && condition2) // outcome 2 only possible for FTF or FTT, condition3 irrelevant
{
Statement2;
return;
}
if (!condition1 && !condition2 && condition3) // outcome 3 only when FFT
{
Statement3;
return;
}
// and for the remaining 5 combinations...
Statement1A;
Statement1B;
Now if we extracted !condition1
(which is present in both ifs
), we would get:
if (!condition1)
{
if (condition2) // outcome 2 only possible for FTF or FTT, condition3 irrelevant
{
Statement2;
return;
}
if (condition3) // outcome 3 only when FFT
{
Statement3;
return;
}
}
// and for the remaining 5 combinations...
Statement1A;
Statement1B;
Which is almost exactly what Kieveli suggested, only his disdain for early return
s caused his implementation to be buggy (as he noted himself), because it wouldn't do a thing if all 3 conditions were false.
Or, we could revert it like so (this probably wouldn't work in every language - it works in C#, for one, since C# allows for equality comparison between multiple variables), now we're virtually back to the first one:
// note that "condition1" on the right side of || is actually redundant and can be removed,
// because if the expression on the right side of || gets evaluated at all,
// it means that condition1 must have been false anyway:
if (condition1 || (condition1 == condition2 == condition3 == false)) // takes care of all 4 x T** plus FFF (the one special case).
{
Statement1A;
Statement1B;
return;
}
// and now it's nice and clean
if (condition2)
{
Statement2;
return; // or "else" if you prefer
}
if (condition3)
{
Statement3;
return; // if necessary
}
if (condition1)
entirely, because it runs the exact same content as theelse
block. Assuming it doesn't cause side effects as jk suggests. That would be pretty 'yuck' indeed. – KChaloux Dec 10 '13 at 13:34if (A) else if (B)
. Removingif (A)
affects the code flow not because checkingA
had some side effect that's missing now. You removed theelse
as well. You changed the code semantically. – Konrad Morawski Dec 10 '13 at 15:34condition1
may be the return value of a method call that also changes state. Also some other things, like in Java,condition1
might be a volatile variable and checking its value results in other changes being seen. – Radiodef Dec 10 '13 at 19:11if-else
block. If those statements do something else, you may need to redactor their logic to make it clean. This question seems almost too general to be useful- I don't think there exists a single applicable use case. – MirroredFate Dec 10 '13 at 20:55condition1&&condition2
? According to the OP, runningstatement2
would be the wrong behavior, which is what your version would do. – SailsMan63 Dec 11 '13 at 04:11condition1
? As far as I can tell from the original, bothif(condition1)
andelse
blocks execute the exact same statements. Hence you only need to checkcondition2
andcondition3
, and simply removecondition1
altogether:if (condition2) { Statement2; return; } else if (condition3) { Statement3; return; } Statement1A; Statement1B; return;
. There is no need for an emptyif(condition1)
block in your refactored code (assuming there are no side effects being removed). – ADTC Sep 10 '14 at 05:08if
blocks which would mean "I only check condition2 and condition3 when condition1 is false. Otherwise I execute 1A and 1B."). But dependent conditions like that could be an indicator of bad code. – ADTC Sep 10 '14 at 05:15