Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java - Complex Decision Table

Tags:

java

Currently have to create a Decision Table that is based on different objects that can each have different/multiple information.

Example:

object A can be: OK / KO
object B can be: OK / WARNING / KO
object C can be: STARTING / RUNNING / ENDING

Depending on A, B and C's status we get a different output. I currently on did lots of IF statements and feel like it's very rookie-ish coding.

Like-so:

if (C == STARTED) {
    if (A == OK) {
        if (B == OK)
            return "something";
        if (B == WARNING)
            return "something else";
        else
            return "something more";
    }
  ...
}

Are there any known technics (using hasmaps or something already in Java 8) that handles this types of issues in a proper way?

Thought of implementing a decision tree but my current if statements take about 30 lines and not sure if it'd be wise to create a (bunch of) whole new class(es) to solve this.

like image 565
JustADude Avatar asked May 07 '26 22:05

JustADude


1 Answers

In fact you have three distinct cases here :

if (C == STARTED) {
    if (A == OK) {
        if (B == OK)
            return "something";
        if (B == WARNING)
            return "something else";
        else
            return "something more";
    }
  ...
}

Separate distinct cases in distinct methods or each one in a class allow to test it unitary, to understand easily each rules and to change it without side effect on other rules.

For example :

if (C == STARTED && (A == OK) && (B == OK) is a rule

if (C == STARTED && (A == OK) && (B == WARNING) is another rule

if (C == STARTED && (A == OK) && (B == KO) is another rule

Either create a method for each one or create an interface with a processing method and make each rule a distinct implementation of it.
Chain of responsibility is a good pattern for this way.

For example you could have these.

Rule interface :

public interface IRule {     
    public void setNextRule(IRule nextRule);
    public abstract boolean apply(Data data);     
}

Abstract common class for rule interface :

public abstract class AbstractRule implements IRule {

    protected IRule nextRule;

    public void setNextRule(IRule nextRule) {
       this.nextRule = nextRule;
    }

    public boolean applyNextRuleIfExist(Data data) {
      if (this.nextRule != null) {
         return this.nextRule.apply(data);
      }
      return false;
    }

}

Concrete rule :

public class RuleXXX extends AbstractRule {

    public boolean apply(Data data) {
        if (data.C == STARTED && (data.A == OK) && (data.B == OK){
           return true;
         }
       return applyNextRuleIfExist(inputDataForDiscountRules);     
    }          
}

And at last you can create the rule chain and use it :

IRule firstRule = new RuleXXX();
firstRule.setNextRule(new RuleYYY());
...
// apply the chain
Data data = ...;
firstRule.apply(data);
like image 79
davidxxx Avatar answered May 10 '26 13:05

davidxxx



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!