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