[Java] "Paramétrage" utilisant Enum plutôt que le branchement conditionnel par instruction if -Strategy Enum

La complexité du branchement conditionnel avec des instructions if

Supposons que vous souhaitiez déterminer si un jour est passé, présent ou futur, et divisez le processus en conséquence. Si cela est implémenté à l'aide de l'instruction if, le code sera le suivant. En fait, les perspectives ne sont pas si mauvaises à ce niveau, mais ** si vous voulez les décomposer davantage, vous devrez lire des branches complexes **.

Main.java


public static void main(String[] args) {	
    //variable:Je veux juger du système du temps passé
    LocalDate past =  LocalDate.of(2019, 10, 11);

    LocalDate today = LocalDate.now();  //Actuellement(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");
        }
    //production: Past
}

"Définition de conditions qui résume le traitement" plutôt que "branchement conditionnel par instruction if"

Avec Strategy Enum, vous pouvez écrire des conditions et le traitement correspondant sur une base individuelle.

Tout d'abord, définissez les deux interfaces fonctionnelles suivantes dans le champ Enum (DatePattern).

  1. Condition: prédicat
  2. Action: exécutable

Ensuite, ici, la méthode Factory est décrite comme la méthode de classe de () de Enum. La méthode Factory détermine le système de temps à partir de la date de réception en tant qu'argument, affecte le traitement en fonction de celui-ci et le renvoie comme valeur de retour.

De cette façon, vous pouvez écrire ** conditions et actions en tant que paramètres **.

DatePattern.java


public enum DatePattern {
    //(conditions,En traitement)paramètres de
    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; //En traitement

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

    /* Factory Method 
     *Une condition qui définit la date locale de l'argument dans le champ(Predicate)À en juger par
     *En traitement(Runnnable)Rendre
    */ 
    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);
    }

    //Jugement du passé
    private static boolean isBeforeToday(LocalDate date) {
        LocalDate today = LocalDate.now();
        return date.isAfter(today);
    }
    //Jugement du futur
    private static boolean isAfterToday(LocalDate date) {
        LocalDate today = LocalDate.now();
        return date.isBefore(today);
    }
    //Jugement de l'état actuel
    private static boolean isSameToday(LocalDate date) {
        LocalDate today = LocalDate.now();
        return date.equals(today);
    }    
}

Suite à l'utilisation de Enum, l'instruction if peut être supprimée comme suit. Puisqu'il n'y a pas de branchement conditionnel, nous avons pu améliorer les perspectives. De plus, l'ajout de conditions de jugement plus détaillées n'affecte pas l'appelant de ce DatePattern. Plutôt que de répéter le branchement conditionnel par instruction if les uns après les autres, je pense personnellement qu'il vaut mieux définir les conditions et le traitement dans un seul ensemble ** dans Enum, et cela améliorera la maintenabilité.

Main.java


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

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

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

Recommended Posts

[Java] "Paramétrage" utilisant Enum plutôt que le branchement conditionnel par instruction if -Strategy Enum
Étude de Java # 4 (branchement conditionnel / instruction if)
[Introduction à Java] Branchement conditionnel (instruction if, instruction if-else, instruction else if, opérateur ternaire, instruction switch)
[Java] Le branchement conditionnel est une instruction if, mais il existe également un opérateur conditionnel.
Modèle de stratégie Enum en Java
java (branchement conditionnel et répétition)