Как избежать огромного условия if, используя BigDecimals?

Я работаю в банковском учреждении, и мне нужно выполнять такие транзакции, как депозит, снятие средств, перевод и т. д. И когда мы рассматриваем поля с большими значениями, я увидел, что BigDecimal обычно используется с Java 8 в приложении Spring Boot.

Когда мне нужно сравнить, является ли это число (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"); 
}

Но если подумать о чистом, поддерживаемом и понятном коде, может ли кто-нибудь поделиться лучшим подходом, например кратким и/или интеллектуальным решением?

Это проверка, чтобы проверить, достигает ли клиент лимита снятия в день в банке транзакций. Мне интересно, как работать с BigDecimal с использованием Java 8 или 11 без этого огромного условия if.

Другим подходом может быть использование подробного кода, но перед этим я надеюсь узнать или получить помощь, чтобы кодировать лучше.

Не стесняйтесь проверить мой полный код здесь.


person Alexandre Barbosa    schedule 25.01.2021    source источник
comment
Проблема на самом деле в том, что вы видите это как огромное условие. Это что-то, к чему трудно относиться.   -  person ernest_k    schedule 25.01.2021
comment
позвольте мне пояснить мою точку зрения, если бы у меня был двойник, который я мог бы иметь: if ((request.getTransactionValue() + totalTransactionValuePerDay) > accountBank.getWithdrawLimitPerDay()) { throw new UnprocessableEntityException("Withdraw limit per day has exceeded"); } это немного лаконично. Мне просто интересно, можно ли быть более кратким из-за моего первого контакта с BigDecimal. Пожалуйста, не стесняйтесь комментировать это @ernest_k   -  person Alexandre Barbosa    schedule 25.01.2021


Ответы (2)


Теперь условное выражение может искать вас дольше (всего 3 переменные!). Но он определенно становится больше, когда вы хотите добавить n BigDecimals и сравнить их с вашими данными.

Как уже ответил Николас, одна немедленная интуиция состоит в том, чтобы переместить их в отдельные методы, выполнить там операцию и вернуть требуемое значение обратно вызывающей стороне.

Другой очень простой реализацией было бы использование операции уменьшения, как показано ниже (удобно, в частности, для добавления нескольких значений, лучшая читаемость также 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));
person Mohamed Anees A    schedule 25.01.2021
comment
Спасибо, Мохамед. - person Alexandre Barbosa; 25.01.2021

К сожалению, Java не поддерживает перегрузку операторов, которая подходила бы для классов BigDecimal и BigInteger (она реализована как синтаксический сахар для конкатенации 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"); 
}
person Nikolas Charalambidis    schedule 25.01.2021
comment
Спасибо, Николас. - person Alexandre Barbosa; 25.01.2021