java - 除了Switch语句和多态之外,如何替换这么多if else条件

标签 java coding-style

与税收系统类似,我必须编写给出一些折扣范围的代码,并且将来我很可能会获得 10-20 个以上的折扣范围。

实际问题陈述:购物车

有多种类型的客户(普通客户、高级客户),他们根据购买金额获得折扣。例如:

高级客户

  1. 0-5000 美元 0%
  2. $5000-$10000 10%
  3. 10000 - 高于 20%

老客户

  1. 0-4000 美元 10%
  2. $4000 - $8000 15%
  3. $8000 - $12000 20%
  4. 12000 美元 - 超过 25%

我尝试了 if-else 和 switch 语句,但情况是一样的。每次我必须接触已经测试过的方法并添加 switch-case 条件或 else-if 部分,或者说 10 个以上的类 if 多态性。

解决存在如此多条件并且可以在将来添加而不触及以前编写的代码的情况的最佳方法是什么

public class PremiumCustomerBillingStrategy extends BillingStrategy {

    @Override
    public double calculateFinalBill(double actualBillAmt) {

        double finalBillAmt;

        if (actualBillAmt <= 4000) {
            finalBillAmt = actualBillAmt - getDiscountedAmount(actualBillAmt, PremiumDiscountEnum.BELOW_FOUR_THOUSAND.discount);
        } else if (actualBillAmt > 4000 && actualBillAmt <= 8000) {
            finalBillAmt = actualBillAmt - getDiscountedAmount(actualBillAmt - 4000, PremiumDiscountEnum.BELOW_EIGHT_THOUSAND.discount)
                    - getDiscountedAmount(4000, PremiumDiscountEnum.BELOW_FOUR_THOUSAND.discount);
        } else if (actualBillAmt > 8000 && actualBillAmt <= 12000) {
            finalBillAmt = actualBillAmt - getDiscountedAmount(actualBillAmt - 8000, PremiumDiscountEnum.BELOW_TWELVE_THOUSAND.discount)
                    - getDiscountedAmount(4000, PremiumDiscountEnum.BELOW_EIGHT_THOUSAND.discount)
                    - getDiscountedAmount(4000, PremiumDiscountEnum.BELOW_FOUR_THOUSAND.discount);
        } else {
            finalBillAmt = actualBillAmt - getDiscountedAmount(actualBillAmt - 12000, PremiumDiscountEnum.ABOVE_TWELVE_THOUSAND.discount)
                    - getDiscountedAmount(4000, PremiumDiscountEnum.BELOW_TWELVE_THOUSAND.discount)
                    - getDiscountedAmount(4000, PremiumDiscountEnum.BELOW_EIGHT_THOUSAND.discount)
                    - getDiscountedAmount(4000, PremiumDiscountEnum.BELOW_FOUR_THOUSAND.discount);
        }
        return finalBillAmt;

    }

最佳答案

在这种情况下,这有点过分了,但如果条件真的很多,您可以使用一个类来表达一个函数来应用金额(如果它在所需的范围内),如下所示:

public class Bills {

class BillFor {
    public final double rangeFrom;
    public final double rangeTo;
    public final Function<Double, Double> calculation;

    BillFor(double rangeFrom, double rangeTo, Function<Double, Double> calculation) {
        this.rangeFrom = rangeFrom;
        this.rangeTo = rangeTo;
        this.calculation = calculation;
    }
}

private final static float MIN = 0f;
private final static float MAX = Long.MAX_VALUE;

private List<BillFor> billings = List.of(new BillFor(MIN, 4000, i -> i - getDiscountedAmount(i, PremiumDiscountEnum.BELOW_FOUR_THOUSAND.discount)),
                /*etc*/
                new BillFor(12000f, MAX, i -> i - 0 /* big expression actually*/));


public double calculateFinalBill(double actualBillAmt) {
    return billings.stream()
            .filter(b -> actualBillAmt > b.rangeFrom  && b.rangeTo <= actualBillAmt)
            .findAny()
            .map(b -> b.calculation.apply(actualBillAmt))
            .orElseThrow(IllegalStateException::new);
}
}

关于java - 除了Switch语句和多态之外,如何替换这么多if else条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58723485/

相关文章:

coding-style - 为什么会有这么多缩进不良的代码?

java - 处理中找不到任何设备

java - 将 SoftReferences 添加到 "Java Concurrency in Practice"中高效且可扩展的结果缓存

java - 使用后将 "null"分配给每个应用程序中的对象

java - 在 Java 中,为什么人们要在字段前面加上 `this` ?

c - 为什么不应该在 linux 内核中将全局变量初始化为 0/NULL/false?

php - 如何制作这样的 PHP 代码?

java - Eclipse Activiti 中的 BPMN 错误

java - Java流将字符串列表排序为数字问题

java - 行添加两次 jtable