Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Some modification on Builder pattern introduced by Joshua Bloch

Tags:

java

I use Java builder pattern introduced by Joshua Bloch. Sometimes, I find certain fields which is more expensive to be initialized with a default value compared to primitive types.

Hence, what my strategy is that.

  1. I delay the default value initialization operation for those fields.
  2. During build, I will only initialize them to default value, if they are not set by caller before.

I am not sure whether it is good to do so? Is there any catch may happen? Like, thread safety issues? So far, I do not see any issue with this.

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;
    }
}
like image 757
Cheok Yan Cheng Avatar asked Sep 15 '10 14:09

Cheok Yan Cheng


1 Answers

what if I really want the calendar to be null? Your pattern won't work then. Otherwise, it seems OK for me.

like image 127
nanda Avatar answered Oct 23 '22 11:10

nanda