如何在Java中避免使用方法选择器参数(标志/布尔参数)

6
我是一位有用的助手,能够翻译文本。
我刚刚完成了《代码整洁之道》,其中之一的原则是避免将布尔参数作为函数选择器传递,例如,
与其这样:
public double calculateWeeklyPay(boolean overtime) {
    double pay = calculatePay();
    if (overtime) {
         return pay *= 1.5;
    }
    return pay;
}

我们应该这样做,让消费者调用适当的方法:
public double calculateWeeklyPay() {
    return calculatePay();
}

public double calculateWeeklyPayWithOvertime() {
    double pay = calculateWeeklyPay();
    return pay *= 1.5;
}

但是在更复杂的方法中,如果分解方法会导致大量重复代码,我应该怎么做?

这里应该怎么做:

public double calculateWeeklyPay(boolean overtime) {

    double pay = calculatePay();
    pay = modifyPay1(pay);
    pay = modifyPay2(pay)
    pay = modifyPay3(pay)
    if (overtime) {
        pay = pay *= 1.5;
    }
    pay = modifyPay4(pay);
    pay = modifyPay5(pay);
    pay = modifyPay6(pay);

}


pay 不会受到 anotherMethodX 的调用影响,所以您可以继续使用您最初提出的方法。我认为这些 布尔标志 只应在极端情况下必要时使用。 - Luiggi Mendoza
好观点,@LuiggiMendoza,但这只是示例代码。我已修改代码以更好地说明问题。 - LimaNightHawk
3个回答

9

您需要区分公共 API内部 API

对于公共 API,您应该尽量避免使用这样的选择器参数。但对于内部 API(私有方法),这是一种适当的实现机制。因此,请按以下方式进行:

public double calculateWeeklyPayWithOvertime() {
    return calculateWeeklyPay(true);
}

public double calculateWeeklyPayWithoutOvertime() {
    return calculateWeeklyPay(false);
}

private double calculateWeeklyPay(boolean overtime) {
    double pay = calculatePay();
    if (overtime) {
         pay *= 1.5;
    }
    return pay;
}

非常优雅的解决方案! - Arash Saidi

0

在第二个例子中,你不是可以做完全相同的事情吗?

public double calculateWeeklyPay() {

double pay = calculatePay();
anotherMethod1(pay);
anotherMethod2(pay)
anotherMethod3(pay)

anotherMethod4(pay);
anotherMethod5(pay);
anotherMethod6(pay);
}

public double calculateWeeklyPayWithOvertime() {
double pay = calculatePay();
anotherMethod1(pay);
anotherMethod2(pay)
anotherMethod3(pay)

    pay = pay *= 1.5;

anotherMethod4(pay);
anotherMethod5(pay);
anotherMethod6(pay);
}

2
当然,但现在我们在两个不同的位置调用这六种方法,我觉得这是重复代码,特别是在那些需要按正确顺序调用这些方法的情况下。 在这种情况下,我个人更喜欢使用选择器调用一个方法。 - LimaNightHawk

0
如果在将方法拆成两个后仍有任何重复的代码块,最好的做法是将重复的代码移至一个私有方法,并在原来重复代码的位置调用该私有方法。
举个例子,而非:
public void trueMethod() {
     //do a few lines 
     // of general stuff

     println("Did the true method");
}

public void falseMethod() {
     //do a few lines 
     // of general stuff

     println("Did the false method");
}

最好这样做:

private void generalMethod() {
     //do a few lines 
     // of general stuff
}


public void trueMethod() {
     generalMethod();

     println("Did the true method");
}

public void falseMethod() {
     generalMethod();

     println("Did the false method");
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接