[Lire le Java efficace] Chapitre 2 Item 2 "Considérez un constructeur face à un grand nombre de paramètres de constructeur"

Considérez le constructeur face à de nombreux paramètres de constructeur

Lors de la création d'une classe qui vous oblige à passer de nombreux paramètres lorsque vous Dire que l'utilisation de "builder" est bonne pour la lisibilité et la sécurité

Exemple de code

La valeur nutritive est une classe qui représente les composants nutritionnels Considérez trois modèles, en prenant comme exemple la quantité pour une personne, la quantité par contenant, les calories pour une personne, etc. ・ Modèle de constructeur télescopique L'inconvénient est que s'il y a beaucoup de paramètres, il sera difficile de comprendre ce qu'il faut passer comme argument lors de la nouveauté, et la lisibilité diminuera également.

・ Modèle JavaBeans Contrairement au modèle de constructeur télescopique, il est plus lisible, mais il crée un état incohérent lors de la définition des paramètres.

・ Modèle de constructeur Le meilleur des constructeurs Terescorping et des JavaBeans!

Exemple 1


//Modèle de constructeur Terescoping
public class NutritionFacts{
    private final int servingSize;  //(mL)Obligatoire
    private final int servings;     //(Par conteneur)Obligatoire
    private final int calories;     //option
    private final int fat;          //(g)option
    private final int sodium;       //(mg)option
    private final int carbohydrate; //(g)option

    public NutritionFacts(int servingSize, int servings){
        this(servingSize, servings, 0, 0, 0, 0);
    }

    public NutritionFacts(int servingSize, int servings, 
             int calories ){
        this(servingSize, servings, calories, 0, 0, 0);
    }
    
    public NutritionFacts(int servingSize, int servings,
            int calories, int fat ){
        this(servingSize, servings, calories, fat, 0, 0);
    }

    public NutritionFacts(int servingSize, int servings,
            int calories, int fat, int sodium ){
        this(servingSize, servings, calories, fat, sodium, 0);
    }

    public NutritionFacts(int servingSize, int servings,
            int calories, int fat, int sodium, carbohydrate ){
        this.servingSize   = servingSize;
        this.servings      = servings;
        this.calories      = calories;
        this.fat           = fat;
        this.sodium        = sodium;
        this.carbohydrate  = carbohydrate;
    }
}

//Il est difficile de voir quand nouveau
NutritionFacts cocaCola = new NutritionFacts(240, 8, 100, 0, 35, 27);

Exemple 2


//Modèle JavaBeans
public class NutritionFacts{
    private int servingSize  = -1; //(mL)Obligatoire
    private int servings     = -1; //(Par conteneur)Obligatoire
    private int calories     = 0;  //           
    private int fat          = 0;  //(g)        
    private int sodium       = 0;  //(mg)       
    private int carbohydrate = 0;  //(g)        

    public NutritionFacts(){ }

    //Setter
    public void setServingSize(int val)  { servingSize = val;}
    public void setServings(int val)     { servings = val;}
    public void setCalories(int val)     { calories = val;}
    public void setFat(int val)          { fat = val;}
    public void setSodium(int val)       { sodium = val;}
    public void setCarbohydrate(int val) { carbohydrate = val;}
}

//Il est facile de voir quand il est neuf, mais c'est un peu un problème s'il est accédé pendant le réglage
NutritionFact cocaCola = new NutritionFacts();
cocaCola.setServingSize(240);
cocaCola.setServings(8);
cocaCola.setCalories(100);
cocaCola.setSodium(35);
cocaCola.setCarbohydrate(27);

Exemple 3


//Modèle de constructeur
public class NutritionFacts{
    private final int servingSize;  //(mL)       
    private final int servings;     //(Par conteneur)
    private final int calories;     //           
    private final int fat;          //(g)        
    private final int sodium;       //(mg)       
    private final int carbohydrate; //(g)        

    public static class Builder{
        //Paramètres requis
        private final int servingSize;  //(mL)       
        private final int servings;     //(Par conteneur)
        
        //Paramètres facultatifs
        private int calories     = 0;  //           
        private int fat          = 0;  //(g)        
        private int sodium       = 0;  //(mg)       
        private int carbohydrate = 0;  //(g)   

        public Builder(int servingSize, int servings){
            this.servingSize = servingSize;
            this.servings    = servings;
       }

       public Builder calories(int val){
            calories = val;
            return this;
       }

       public Builder fat(int val){
            fat = val;
            return this;
       }

       public Builder sodium(int val){
            sodium = val;
            return this;
       }

       public Builder carbohydrate(int val){
            carbohydrate = val;
            return this;
       }

       public NutritionFacts build() {
           return new NutritionFacts(this);
       }
    }

    private NutritionFacts(Builder builder){
         servingSize  = builder.servingSize;
         servings     = builder.servings;
         calories     = builder.calories;
         fat          = builder.fat;
         sodium       = builder.sodium;
         carbohydrate = builder.carbohydrate;
    }
}

//Facile à voir et sûr lorsqu'il est neuf!
NutritionFacts cocaCola = new NutritionFacts.Builder(240, 8).
    calories(100).sodium(35).carbohydrate(27).build();

Recommended Posts

[Lire le Java efficace] Chapitre 2 Item 2 "Considérez un constructeur face à un grand nombre de paramètres de constructeur"
[Lire Java efficace] Chapitre 2 Item 4 "Forcer l'impossibilité d'immobilisation avec un constructeur privé"
[Lire Java efficace] Chapitre 2 Item 1 "Considérez les méthodes de fabrique statiques plutôt que les constructeurs"
[Lire Java efficace] Chapitre 3 Point 12 "Considérer l'implémentation de Comparable"
[Lire Java efficace] Chapitre 2 Item 3 "Forcer les caractéristiques de singleton avec un constructeur privé ou un type enum"
[Lire Java effectif] Chapitre 3 Rubrique 9 "Lors de la substitution d'égaux, toujours remplacer hashCode"
[Lire Java efficace] Chapitre 2 Item 5 "Eviter la création d'objets inutiles"
[Lire Java efficace] Chapitre 2 Item 7 "Eviter les finaliseurs"
[Lire Java efficace] Chapitre 3 Point 8 "En cas de remplacement égal, suivez le contrat général"
[Lire Java efficace] Chapitre 3 Item 10 "Always Override toString"
[Lire Java efficace] Chapitre 2 Item 6 "Supprimer les références d'objets obsolètes"
[Java] JUnit qui NG lorsqu'une méthode avec un grand nombre de lignes est détectée en utilisant la magie noire
Forcer non immuable avec le constructeur privé Effective Java