5 votes

Quelques modifications sur le modèle Builder introduit par Joshua Bloch

J'utilise le modèle de construction Java introduit par Joshua Bloch. Parfois, je trouve certains champs dont l'initialisation avec une valeur par défaut est plus coûteuse que celle des types primitifs.

C'est pourquoi ma stratégie est la suivante.

  1. Je retarde l'opération d'initialisation de la valeur par défaut pour ces champs.
  2. Lors de la construction, je ne les initialiserai à la valeur par défaut que s'ils n'ont pas été définis par l'appelant auparavant.

Je ne sais pas si c'est bon de le faire ? Y a-t-il un risque d'attraper quelque chose ? Comme des problèmes de sécurité du fil ? Jusqu'à présent, je ne vois aucun problème.

package sandbox;

import java.util.Calendar;

/**
 *
 * @author yccheok
 */
// Builder Pattern
public class NutritionFacts {
    private final int servingSize;
    private final int servings;
    private final int calories;
    private final int fat;
    private final int sodium;
    private final int carbohydrate;

    private final java.util.Calendar calendar;    // !!!

    public static class Builder {
        // Required parameters
        private final int servingSize;
        private final int servings;
        // Optional parameters - initialized to default values
        private int calories = 0;
        private int fat = 0;
        private int carbohydrate = 0;
        private int sodium = 0;

        // We suppose to provide a default value for calendar. However, it may
        // seem expensive. We will do it later during build.        
        private java.util.Calendar calendar = null;

        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 carbohydrate(int val)
        { carbohydrate = val; return this; }
        public Builder sodium(int val)
        { sodium = val; return this; }

        public NutritionFacts build() {
            // !!!
            if (this.calendar == null) {
                this.calendar = Calendar.getInstance();
            }            
            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;
        calendar = builder.calendar;
    }
}

4voto

nanda Points 12764

Que faire si je veux vraiment que le calendrier soit nul ? Dans ce cas, votre modèle ne fonctionnera pas. Sinon, cela me semble correct.

3voto

NG. Points 12989

Je n'y vois pas d'inconvénient. Le modèle Builder est en fait une API qui aide à accomplir certaines tâches. Vous pouvez faire ce que vous voulez sous la couverture de l'API tant que vous adhérez aux principes du modèle/API. Je pense que le chargement paresseux de ressources coûteuses est acceptable, assurez-vous simplement de documenter tout comportement que vous pensez que les développeurs devraient connaître.

2voto

hhbarriuso Points 946

Attention, le calendrier étant mutable, il convient de ne pas le copier dans le constructeur de NutritionFacts.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X