Stef
Stef

Reputation: 314

Checking "rules" in Java without lots of if statements

I'm creating a springboot banking API and in order to create a transaction a bunch of "rules" have to be checked.

e.g:

This causes my createTransaction method to contain a lot of if statements (12!). This is what my code looks like in pseudo:

public ResponseEntity<String> createTransaction(Transaction body) {
    if (check rule 1) {
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("...");
    }
    if (check rule 2) {
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("...");
    }
    // etc...

    // Transaction complies to set rules
    return ResponseEntity.status(HttpStatus.CREATED).body("Transaction successful!");
}

I can post my actual code if necessary but I think this paints the picture without having anyone to read 100 lines of code.

Because I have around 12 if statements checking these rules, my function is quite lengthy and difficult to read/maintain. Googling for a solution didn't bring up results I was looking for. I've tried implementing exceptions but this didn't remove the amount of if statements. Maybe a switch could improve a bit, but I'm wondering if there's a clean OOP solution.

My question is: How can I clean this code up (OOP style)?

Thanks in advance.

Upvotes: 1

Views: 507

Answers (1)

Titulum
Titulum

Reputation: 11486

You should create a TransactionRule interface that allows you to implement specific transaction rules, and then use a stream to get the final result:

public interface TransactionRule {
  public boolean isAllowed(Transaction someTransaction);
}

Example implementation 1:

public class SufficientBudgetTransactionRule implements TransactionRule {
  public boolean isAllowed(Transaction someTransaction) {
    // Custom logic e.g. 
    return someTransaction.wallet.value >= someTransaction.transaction.value;
  }
}

Example implementation 2:

public class NotInFutureTransactionRule implements TransactionRule {
  public boolean isAllowed(Transaction someTransaction) {
    // Custom logic e.g. 
    return someTransaction.transaction.datetime.isBefore(OffsetDateTime.now());
  }
}

Then, you can store all the TransactionRules in a List and check whether they all validate like so:

private final List<TransactionRule> transactionRules; // Fill these of course

public boolean allTransactionRulesMatch(Transaction someTransaction) {
  return transactionRules.stream()
    .map(transactionRule -> transactionRule.isAllowed(someTransaction))
    .allMatch(result => result);
}

Upvotes: 1

Related Questions