[Java] "Setting" using Enum rather than conditional branching by if statement -Strategy Enum

Complexity of conditional branching by if statement

Suppose you want to determine if a day is past, present, or future, and divide the process accordingly. If this is implemented using an if statement, the code will be as follows. In fact, the outlook isn't that bad at this level, but ** if you want to break it down further, you'll have to read through complex branches **.

Main.java


public static void main(String[] args) {	
    //variable:I want to judge the tense of past
    LocalDate past =  LocalDate.of(2019, 10, 11);

    LocalDate today = LocalDate.now();  //Currently(2019-10-12)
        if(past.isBefore(today)) {
            System.out.println("Past");
        } 
        if(past.isEqual(today)) {
            System.out.println("Today");
        }
        if(past.isAfter(today)) {
	        System.out.println("After");
        }
    //output: Past
}

"Condition-setting that summarizes processing" rather than "conditional branching by if statement"

With Strategy Enum, you can write conditions and corresponding processing on a one-to-one basis.

First, define the following two functional interfaces in the Enum (DatePattern) field.

  1. Condition: Predicate
  2. Action: Runnable

Next, here, describe the Factory Method as the class method of () of Enum. The Factory Method determines the tense from the date received as an argument, assigns the corresponding processing, and returns it as a return value.

This way, you can write ** conditions and actions as settings **.

DatePattern.java


public enum DatePattern {
    //(conditions,processing)settings of
    Past(date -> isBeforeToday(date), () -> System.out.println("Past")),
    Today(date -> isSameToday(date), () -> System.out.println("Today")),
    Future(date -> isAfterToday(date), () -> System.out.println("Future"));

    private final Predicate<LocalDate> dateValidator; //conditions
    private final Runnable function; //processing

    //Enum constructor
    DatePattern(Predicate<LocalDate> dateValidator, Runnable function) {
        this.dateValidator = dateValidator;
        this.function = function;
    }

    /* Factory Method 
     *Condition that defines the tense of Local Date of the argument in the field(Predicate)Judging by
     *processing(Runnnable)To return
    */ 
    public static Runnable of(LocalDate date) {
        Optional<Runnable> pattern = Stream.of(DatePattern.values())
                .filter(e -> e.dateValidator.test(date))
                .map(e -> e.function)
                .findFirst();
        return Optional.ofNullable(pattern.get()).orElseThrow(IllegalArgumentException::new);
    }

    //Judgment of past
    private static boolean isBeforeToday(LocalDate date) {
        LocalDate today = LocalDate.now();
        return date.isAfter(today);
    }
    //Judgment of the future
    private static boolean isAfterToday(LocalDate date) {
        LocalDate today = LocalDate.now();
        return date.isBefore(today);
    }
    //Judgment of current status
    private static boolean isSameToday(LocalDate date) {
        LocalDate today = LocalDate.now();
        return date.equals(today);
    }    
}

As a result of using Enum, the if statement can be deleted as follows. Since there is no conditional branching, we were able to improve the outlook. Also, adding more detailed judgment conditions does not affect the caller of this DatePattern. Rather than repeating conditional branching by if statement one after another, I personally think that it is better to set conditions and processing in one set ** in Enum, and maintainability will be improved.

Main.java


public static void main(String[] args) {
    LocalDate past =  LocalDate.of(2019, 10, 11);  //past
    LocalDate today = LocalDate.of(2019, 10, 12);  //Current(2019-10-12)
    LocalDate future = LocalDate.of(2019, 10, 13); //future

    Runnable past_function = DatePattern.of(past);
    Runnable today_function = DatePattern.of(today);
    Runnable futute_function = DatePattern.of(future);

    past_function.run();
    //output: Past
    today_function.run();
    //output: Today
    futute_function.run();
    //output: Future
}

Recommended Posts

[Java] "Setting" using Enum rather than conditional branching by if statement -Strategy Enum
Try using conditional branching other than if statement
Java study # 4 (conditional branching / if statement)
[Introduction to Java] Conditional branching (if statement, if-else statement, else if statement, ternary operator, switch statement)
[Java] Conditional branching is an if statement, but there is also a conditional operator.
Program using conditional branching
Enum Strategy pattern in Java
java (conditional branching and repetition)
[Ruby] conditional branch if statement