如何使用 BigDecimals 避免巨大的 if 条件?

问题描述

我在银行机构工作,我需要执行存款、取款、转账等交易。当我们考虑具有大值的字段时,我发现在 Spring Boot 应用程序中使用 Java 8 的 BigDecimal 很常见.

当我必须比较该数字 (BigDecimal) 是大于还是小于其他数字时,我了解到我们需要使用 compareto() 方法。在我的示例中,我需要对两个值求和并将结果与​​第三个数字进行比较,正如我在以下示例中分享的那样,使用 Java 8 和 BigDecimal:

if ((request.getTransactionValue().add(BigDecimal.valueOf(totalTransactionValuePerDay))).compareto(accountBank.getWithdrawLimitPerDay())
    > 0) {
            throw new UnprocessableEntityException("Withdraw limit per day has exceeded"); 
}

但是考虑到干净、可维护和易于理解的代码,有人可以分享更好的方法,例如简洁和/或智能的解决方案吗?

验证客户在交易银行是否达到每天取款限额。我想知道如何在没有这么大的 if 条件的情况下使用 Java 8 或 11 处理 BigDecimal。

另一种方法可能是使用冗长的代码,但在此之前我希望找出或获得帮助以更好地编码。

请随时查看我的完整代码 here

解决方法

不幸的是,Java 不支持适用于 BigDecimalBigInteger 类的运算符重载(它被实现为使用 String 连接 + 的语法糖) .

避免这种长条件的唯一方法是将其拆分为变量(也可能拆分为方法或类)。对于这种特殊情况:

BigDecimal increment = BigDecimal.valueOf(totalTransactionValuePerDay);
BigDecimal transactionValue = request.getTransactionValue();
BigDecimal withdrawLimitPerDay = accountBank.getWithdrawLimitPerDay();

if (transactionValue.add(increment).compareTo(withdrawLimitPerDay) > 0) {
    throw new UnprocessableEntityException("Withdraw limit per day has exceeded"); 
}
,

条件现在可能对您来说更长时间(只有 3 个变量!在手)。但是当您想要添加 n 个 BigDecimal 并将它们与您的数据进行比较时,它肯定会变得更大。

正如尼古拉斯已经回答的那样,一种直接的直觉是将它们移到单独的方法中,在那里执行操作并将所需的值返回给调用者。

其他非常简单的实现是使用如下所示的 reduce 操作(特别方便添加多个值,IMO 的可读性也更好),

BigDecimal bigDecimal1 = new BigDecimal(1);
BigDecimal data = new BigDecimal(3);

Stream.of(bigDecimal1,BigDecimal.valueOf(2)) // Can be generalised/refactored as a Function<Stream<BigDecimal>,BigDecimal> 
    .reduce(BigDecimal.ZERO,BigDecimal::add) // Identity for sum,and Accumulator.
    .compareTo(data));