Reducing complex nested
if
s and
else
s is not a trivial task. This is a typical refactoring task which first of all calls for a good unit test coverage.
Now, how to tackle the problem in a systematic manner?
1. No restructuring but combine common terms into functions
I suggest to first not change the structure but simplify by combining common elaborate conditions into predicate functions. In your case (assuming names starting on capital letters are members of the class), convert
if (length >= 24 && Acct == strAcct && ...
...
else if (length >= 24 && Acct == strAcct && ...
into
bool IsAcct(int length, string strAcct)
{
return length >= 24 && Acct == strAcct;
}
...
if (IsAcct(length, strAcct) && ...
...
else if (IsAcct(length, strAcct) && ...
Likewise convert
if (Effect != strReceive && strVal == "A") ...
into
bool IsDesiredEffect(string strReceive, string strVal)
{
return Effect != strReceive && strVal == "A";
}
...
if (IsDesiredEffect(strReceive, strVal)) ...
2. List all conditions for each code branch
This is best done by first give each simple condition a code, e.g.
The decorated code looks like this
if (IsAcct(length, strAcct) && code == strCode1)
{
if (Box.HasValues)
{
if (alk.Count > 1)
{
if (IsDesiredEffect(strReceive, strVal))
{
Method1();
}
else
{
Method2();
}
}
else
{
Method2();
}
}
}
else if (IsAcct(length, strAcct) && code == strCode2)
{
if (Box.HasValues)
{
Method3();
}
}
This results in the following conditions for the methods
Method1()
Method2()
Method3()
3. Re-arrange and simplify expressions
Here you need to know basics of Boolean logic transformations.
Method1()
Method2()
Method3()
Uncluttered:
Method1()
Method2()
Method3()
4. Combining common expressions again
E.g.
Method1()
Method2()
Method3()
While extending the predicates accordingly:
...
bool IsAcct(int length, string strAcct)
{
return length >= 24 && Acct == strAcct && Box.HasValue;
}
bool IsDesiredEffect(ICollection alk, string strReceive, string strVal)
{
return alk.Count > 1 && Effect != strReceive && strVal == "A";
}
5. Finally composing the reduced version
if (IsAcct(length, strAct))
{
if (code == strCode1)
{
if (IsDesiredEffect(alk, strReceive, strVal))
{
Method1();
}
else
{
Method2();
}
}
else if (code == strCode2)
{
Method3();
}
}
Summary
This approach might look a bit overwhelming, I agree. But it provides you with a systematic approach for such complex transformation. The approach with the codes for the expressions (A, C, D, etc.) allows for easier dealing with the Boolean expression transformations. It also helps in a peer review/pair programming to have the condensed logic to discuss rather than having the logic cluttered with code details.
Don't forget to start with a good set of unit tests before refactoring decision trees!
Have fun!
Cheers
Andi