lundi 27 juillet 2020

java: too many if-statements

I have a service that is becoming too bloated and hard to read because it has too many if statements. For the sake of simplicity, let us say that we have this object:

public class Holiday{
    private Enum type;
    private LocalDate date;
    private LocalTime begin;
    private LocalTime end;
    private boolean active;     
}

In my Service I need to perform some logic if two or more holidays fall on the same day. This is where it gets complicated, because I have to check different use cases.

For example:

public class MyService{

if (holiday1 == PUBLIC && holiday2 == CUSTOM) {
  if (holiday1.getDayTime() == FULL_DAY && holiday2.getDayTime() != FULL_DAY) {
      DayTimeEnum dayTime = getDayTimeOfHoliday(holiday2.getBegin(), holiday2.getEnd());
      
      if (dayTime == FULL_DAY) {
         //doSomething...             
      }
      
      if (dayTime == SECOND_HALF_OF_DAY) {
         //doSomething...         
      }
      //....and much more if-statements....  
  }
}

The code above is only pseudocode to show the nature of my problem. In my real implementation, I need to do much more checks and validations. So my code get's very messy and not reusable...

I did some research and tried to figure out alternatives that are less hard coded and uses less if statements.

The idea would be to have some validation-rules in an own class and make them reusable everywhere. I would like to be able to chain/combine these rules, depending on the use-case.

I am trying to refactor the code in a functional approach. I would like to have a list of functions/behaviors, that I can apply and combine if necessary.

I've looked at the functional interfaces and I like the idea of combining predicates, so I would like to achieve a similar approach as this:

Predicate<String> predicate1 =  str -> str.startsWith("J");
Predicate<String> predicate2 =  str -> str.length() < 4;
List<String> result = names.stream().filter(predicate1.or(predicate2)) //I also could combine them 
with predicate1.and(predicate2)
.collect(Collectors.toList());

I thought of defining all my checks as predicates in a class and using them in different places where needed, however predicates can only be used on collections.

Is there a better way of achieving this?

btw, I am using Spring-Boot and Java 11.

Aucun commentaire:

Enregistrer un commentaire