Can anyone suggest best way to avoid most if conditions? I have below code, I want avoid most of cases if conditions, how to do it ? any solution is great help;
if (adjustment.adjustmentAccount.isIncrease) {
if (adjustment.increaseVATLine) {
if (adjustment.vatItem.isSalesType) {
entry2.setDebit(adjustment.total);
entry2.setCredit(0d);
} else {
entry2.setCredit(adjustment.total);
entry2.setDebit(0d);
}
} else {
if (adjustment.vatItem.isSalesType) {
entry2.setCredit(adjustment.total);
entry2.setDebit(0d);
} else {
entry2.setDebit(adjustment.total);
entry2.setCredit(0d);
}
}
} else {
if (adjustment.increaseVATLine) {
if (adjustment.vatItem.isSalesType) {
entry2.setCredit(adjustment.total);
entry2.setDebit(0d);
} else {
entry2.setDebit(adjustment.total);
entry2.setCredit(0d);
}
} else {
if (adjustment.vatItem.isSalesType) {
entry2.setDebit(adjustment.total);
entry2.setCredit(0d);
} else {
entry2.setCredit(adjustment.total);
entry2.setDebit(0d);
}
}
}
So, how do you refactor multiple nested if statements? The easiest possible way is to use guard clauses. A guard clause is an if statement that checks for a condition and favors early exit from the current method. If the condition is satisfied, the if block returns from the method.
You can place or nest an If statement inside another If statement. When you nest If statements, you can check for a condition only when another condition is found to be true.
How to go about this... Let's extract a couple of methods, so we can better see the logic.
private void a() {
entry2.setDebit(adjustment.total);
entry2.setCredit(0d);
}
private void b() {
entry2.setCredit(adjustment.total);
entry2.setDebit(0d);
}
if (adjustment.adjustmentAccount.isIncrease) {
if (adjustment.increaseVATLine) {
if (adjustment.vatItem.isSalesType) {
a();
} else {
b();
}
} else {
if (adjustment.vatItem.isSalesType) {
b();
} else {
a();
}
}
} else {
if (adjustment.increaseVATLine) {
if (adjustment.vatItem.isSalesType) {
b();
} else {
a();
}
} else {
if (adjustment.vatItem.isSalesType) {
a();
} else {
b();
}
}
So now, looking at it, that first block
if (adjustment.increaseVATLine) {
if (adjustment.vatItem.isSalesType) {
a();
} else {
b();
}
} else {
if (adjustment.vatItem.isSalesType) {
b();
} else {
a();
}
}
just amounts to doing a()
if adjustment.increaseVATLine
has the same value as adjustment.vatItem.isSalesType
, b()
otherwise. So we can reduce it:
if (adjustment.adjustmentAccount.isIncrease) {
if (adjustment.increaseVATLine == adjustment.vatItem.isSalesType) {
a();
} else {
b();
}
} else {
if (adjustment.increaseVATLine) {
if (adjustment.vatItem.isSalesType) {
b();
} else {
a();
}
} else {
if (adjustment.vatItem.isSalesType) {
a();
} else {
b();
}
}
}
And the remaining block is the same, just reversing a()
and b()
:
if (adjustment.adjustmentAccount.isIncrease) {
if (adjustment.increaseVATLine == adjustment.vatItem.isSalesType) {
a();
} else {
b();
}
} else {
if (adjustment.increaseVATLine == adjustment.vatItem.isSalesType) {
b();
} else {
a();
}
}
So we begin to see the logic. If it's an increase, and the increaseVATLine matches the isSalesType, then we debit, otherwise credit, but if it's a decrease, then we credit only if they don't match. What's a good way of expressing this? Well, for one, name a() and b() smarter - now that we can see what they're doing
if (adjustment.adjustmentAccount.isIncrease) {
if (adjustment.increaseVATLine == adjustment.vatItem.isSalesType) {
debitEntry();
} else {
creditEntry();
}
} else {
if (adjustment.increaseVATLine == adjustment.vatItem.isSalesType) {
creditEntry();
} else {
debitEntry();
}
}
And now it's a little clearer still. Debit the account when it's an increase account and an increase VAT line, and a sales type, or when it's a decrease and either it's a decrease VAT line OR it's a sales type, but not both. Does this truth table help? First column is adjustmentAmount.isIncrease
; second is adjustment.increaseVATLine
; third is adjustment.vatItem.isSalesType
. Fourth column is D for debit, C for credit; in parentheses are the number of TRUE values among the flags.
TTT -> D (3)
TFF -> D (1)
TTF -> C (2)
TFT -> C (2)
FTT -> C (2)
FFF -> C (0)
FTF -> D (1)
FFT -> D (1)
Now you can see why @Xavier Ho's solution works; the odd totals are all debits, the even ones all credits.
This is just one exploratory path; I hope it's helpful.
I haven't thoroughly verified the logic, but this is the basic idea:
amt = adjustment.total
if (adjustment.adjustmentAccount.isIncrease
^ adjustment.increaseVATLine
^ adjustment.vatItem.isSalesType)
{
amt = -amt;
}
entry2.setCredit(amt > 0 ? amt : 0);
entry2.setDebit(amt < 0 ? -amt : 0);
I should note that this logic is slightly different in that it correctly handles a negative value of adjustment.total
, whereas the original seems to assume (perhaps correctly) that the value will always be non-negative.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With