mardi 26 novembre 2019

Java Builder Pattern implementation, which one is better?

Looking at Joshua Bloch's way of doing builder pattern in java I have this class:

public class NutritionFacts {
  private final int calories;
  private final int fat;
  private final int sodium;

  public static class Builder {

    private int calories = 0;
    private int fat = 0;
    private int sodium = 0;

    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() {
      return new NutritionFacts(this);
    }
  }
  private NutritionFacts(Builder builder) {
    calories = builder.calories;
    fat = builder.fat;
    sodium = builder.sodium;
  }
}

which I can invoke this way to instantiate a NutritionFacts object:

NutritionFacts cocacola = new NutritionFacts.Builder().calories(140).build()

There is also a slight variation where I can have this class:

public class NutritionFacts {
      private final int calories;
      private final int fat;
      private final int sodium;

      public static class Builder {

        private int calories = 0;
        private int fat = 0;
        private int sodium = 0;

        private Builder(){
        }

        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() {
          return new NutritionFacts(this);
        }
      }

      public static Builder builder(){
       return new Builder()
      }

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

And now I can do this to create an instance of NutritionFacts:

NutritionFacts cocacola = NutritionFacts.builder().calories(140).build()

What should be the preferred way to apply the builder pattern? Are the two mentioned approaches exactly the same in terms of results (clean, immutability, ecc.). Is anything wrong with second approach?

I'd like to have your expert opinion on this.

Aucun commentaire:

Enregistrer un commentaire