任何人都可以提出最好的方法来避免大多数条件吗?我有下面的代码,我想避免大多数情况下如果条件,怎么办呢?任何解决方案都是很有帮助的;
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);
}
}
}
答案 0 :(得分:18)
如何解决这个问题......让我们提取几种方法,以便我们更好地了解逻辑。
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();
}
}
现在,看看它,第一个阻止
if (adjustment.increaseVATLine) {
if (adjustment.vatItem.isSalesType) {
a();
} else {
b();
}
} else {
if (adjustment.vatItem.isSalesType) {
b();
} else {
a();
}
}
如果a()
与adjustment.increaseVATLine
具有相同的值,则{p>仅等于执行adjustment.vatItem.isSalesType
,否则为b()
。所以我们可以减少它:
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();
}
}
}
剩下的区块是相同的,只是反转a()
和b()
:
if (adjustment.adjustmentAccount.isIncrease) {
if (adjustment.increaseVATLine == adjustment.vatItem.isSalesType) {
a();
} else {
b();
}
} else {
if (adjustment.increaseVATLine == adjustment.vatItem.isSalesType) {
b();
} else {
a();
}
}
所以我们开始看到逻辑。如果它是一个增加,并且increaseVATLine匹配isSalesType,那么我们借记,否则信用,但如果它是减少,那么我们只有在它们不匹配时才会记入。表达这个的好方法是什么?那么,对于一个人来说,将a()和b()命名为更聪明 - 现在我们可以看到他们正在做什么
if (adjustment.adjustmentAccount.isIncrease) {
if (adjustment.increaseVATLine == adjustment.vatItem.isSalesType) {
debitEntry();
} else {
creditEntry();
}
} else {
if (adjustment.increaseVATLine == adjustment.vatItem.isSalesType) {
creditEntry();
} else {
debitEntry();
}
}
现在它仍然有点清晰。当帐户是增加帐户和增加的增值税行,销售类型,或者减少时,借记帐户,或者减少增值税行或者是销售类型,但不是两者。这个真相表有帮助吗?第一列是adjustmentAmount.isIncrease
;第二个是adjustment.increaseVATLine
;第三是adjustment.vatItem.isSalesType
。第四栏是D代表借方,C代表贷方;在括号中是标志中的TRUE值的数量。
TTT -> D (3)
TFF -> D (1)
TTF -> C (2)
TFT -> C (2)
FTT -> C (2)
FFF -> C (0)
FTF -> D (1)
FFT -> D (1)
现在您可以看到为什么@Xavier Ho的解决方案有效;奇数总数都是借方,偶数都是贷方。
这只是一条探索之路;我希望它有用。
答案 1 :(得分:8)
我还没有彻底验证逻辑,但这是基本的想法:
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);
我应该注意到这个逻辑略有不同,因为它正确地处理了adjustment.total
的负值,而原始似乎假设(可能是正确的)该值总是非负的。
答案 2 :(得分:6)
你可以使用这样的真值表:
debit = ((isIncrease && increaseVATLine && !isSalesType) ||
(isIncrease && !increaseVATLine && isSalesType) ||
(!isIncrease && increaseVATLine && isSalesType) ||
(!isIncrease && !increaseVATLine && !isSalesType)) ? 0 : adjustment.total;
entry2.setCredit(debit);
没有任何ifs,你可以很容易地看到借记卡是0.同样的信用额度。
答案 3 :(得分:6)
我认为这很有效。我基本上概括了你的布尔逻辑。下次,尝试绘制一些图表以帮助您清除思路。
编辑:我想从本文的评论中指出,Marcelo和BlueRaja提供的XOR解决方案功能相同。
/* This is to avoid a crazy 3-way switch. Generalised.
* Instead of using a complicated if-else branch, we can use the number of true
* and false to entail the intended action. */
/* This is the same as a ^ b ^ c (chained XOR),
* which is used to count the parity of truth values. */
int a = adjustment.adjustmentAccount.isIncrease ? 1 : 0;
int b = adjustment.increaseVATLine ? 1 : 0;
int c = adjustment.vatItem.isSalesType ? 1 : 0;
if ((a + b + c) % 2 == 1)
{
entry2.setDebit(adjustment.total); // Odd number of trues
entry2.setCredit(0d);
}
else
{
entry2.setCredit(adjustment.total); // Even number of trues
entry2.setDebit(0d);
}
答案 4 :(得分:5)
马丁史密斯评论我将补充:
请记住,Karnaugh可以帮助您简化条件。
答案 5 :(得分:4)
问题已得到解答,但我会在这里发布那些关心更清洁解决方案的人:
//Set debit if exactly one or all three are true, else set credit
if(adjustment.adjustmentAccount.isIncrease ^ adjustment.increaseVATLine ^
adjustment.vatItem.isSalesType)
{
entry2.setDebit(adjustment.total);
entry2.setCredit(0d);
}
else
{
entry2.setCredit(adjustment.total);
entry2.setDebit(0d);
}
答案 6 :(得分:3)
看起来你只有2个案例,所以你可以将它们与OR等结合起来。
if (<case1expression>) {
entry2.setCredit(adjustment.total);
entry2.setDebit(0d);
} else {
entry2.setDebit(adjustment.total);
entry2.setCredit(0d);
}
答案 7 :(得分:1)
如果你有条件逻辑(例如,如果满足条件就做某事),你为什么要试着避免它们呢?
答案 8 :(得分:1)
在一定程度上通常可以采取的措施是继承。
例如,如果您有两个类Increase
和NonIncrease
,它们是同一个超类的子类,那么您可以使用方法doSomething
来做 - 根据您目前的任何类别有。然后你不必检查“如果对象是做X”,而只是调用.doSomething()并且它会做它想做的任何事情。
然后你可以更进一步,拥有越来越多的子类来进一步“细化”和“避免更多的ifs”。
可能还有其他可能性(主要取决于您的环境/要求),如函数指针,委托,strategy pattern (GoF)或此类构造。
答案 9 :(得分:1)
最佳解决方案是遵循设计模式。 基于状态的设计模式为每个州定义一个类。
然后状态类封装了该特定状态的操作过程。 这不仅可以防止大量的if -else语句网格。