I am trying to implement Rule engine desing pattern in my use case but not able to fit the pieces in the right place.
RuleEngine is where all rules are validated for a transaction before making it approved
public class RuleEngine {
private Predicate<Transaction> predicates;
private Transaction transaction;
public void setTransaction(Transaction transaction){
this.transaction = transaction;
}
public void addRules(Predicate<Transaction> predicates) {
this.predicates = predicates;
}
public void executeRules() {
if(predicates.test(transaction)) {
// all rules are valided - payment success
}
}
}
Below Payments class is invoked by parent where transaction and its type are provided.
Then based on transaction, rules are added which is the difficult part.
Because of transactionUtils - hard dependency required to autowired, causing predicate chaining looks very ugly and seems not the correct way.
@Component
public class Payments {
@Autowired
PredicateHelper predicateHelper;
public void process(Transaction transaction, String type) {
RuleEngine ruleEngine = new RuleEngine();
ruleEngine.setTransaction(transaction);
switch (type) {
case "card" :
ruleEngine.addRules(getCardRules());
break;
case "cash" :
ruleEngine.addRules(getCashRules());
break;
default : log.error("Invalid case");
}
ruleEngine.executeRules();
}
private Predicate<Transaction> getCardRules(){
return predicateHelper.rule1
.and(predicateHelper.rule2)
.and(predicateHelper.rule3); // Predicate chaining
}
private Predicate<Transaction> getCashRules(){
return predicateHelper.rule1
.and(predicateHelper.rule4)
.and(predicateHelper.rule5); // Predicate chaining
}
}
@Component
public class PredicateHelper {
@Autowired
TransactionUtils transactionUtils; // hard dependency - in house library
public Predicate<Transaction> rule1 = transaction -> "rule1".equals(transactionUtils.getName(transaction));
public Predicate<Transaction> rule2 = transaction -> "rule2".equals(transactionUtils.getName(transaction));
public Predicate<Transaction> rule3 = transaction -> "rule3".equals(transactionUtils.getName(transaction));
public Predicate<Transaction> rule4 = transaction -> "rule4".equals(transactionUtils.getName(transaction));
public Predicate<Transaction> rule5 = transaction -> "rule5".equals(transactionUtils.getName(transaction));
}
Is there a ways to have better predicate chaining with this solution. Thanks in advance.
Aucun commentaire:
Enregistrer un commentaire