mardi 19 février 2019

Conditional Logic to Determine Correct Status String

There is a status variable in a Java application that can be set to one of many statutes, depending on many conditions. The status field is a String. When a condition is met, the status should be returned immediately, as follows:

e.g

String status = "";

if (condition1) {
  return "STATUS_1";
} else if (condition2) {
  return "STATUS_2";
} else if (condition3) {
  return "STATUS_3";
} else if (condition4) {
  return "STATUS_4";
}
...
else if (condition10) {
  return "STATUS_10";
}

I've considered which pattern would be best to make this code more SOLID... e.g. if a new condition is required then this class would need to edited to add the new condition, which would break the open / closed SOLID principle

I've looked at the Strategy Pattern, in particular "Replace Conditional Logic with Strategy", however that seems more appropriate when you want to decide on just one calculation / operation to use... My scenario does not seem to fit the Strategy Pattern as my logic determines the status, rather than determining which individual operation to execute - I need to run all the conditions until one is true

I wondered if the following pattern could work...

Have an interface as follows

public interace StatusCondition {
  boolean condition(Context context);
  String getStatus();
}

With an implementation as follows:

public class StatusAStatusCondition implements StatusCondition {

  boolean condition(Context context){
    return context.getValue1() == 0 && context.getValue2().equals("A");
  }

  String getStatus(){
    return "STATUS_A";
  }
}

This would allow a list of StatusCondition classes to be executed in order and return the status of the first StatusCondition where the condition() method returns true. e.g:

public String getStatus(List<StatusCondition> statusConditions) {
  for (StatusCondition statusCondition : statusConditions) {
    if (statusCondition.condition()) {
      return statusCondition.getStatus();
    }
  }
  return "";
}


usage:

List<StatusCondition> statusConditions = new ArrayList<>();
statusConditions.add(StatusAStatusCondition);
statusConditions.add(StatusBStatusCondition);
statusConditions.add(StatusCStatusCondition);
statusConditions.add(StatusDStatusCondition);
statusConditions.add(StatusEStatusCondition);
statusConditions.add(StatusFStatusCondition);
...

String status = getStatus(statusConditions);

To me this solves the open closed principle issue and also ensures the implementations are single responsibility... My question is, how could this pattern i've suggested be improved, or is there a pattern better suited to my scenario?

Aucun commentaire:

Enregistrer un commentaire