不可变对象构建器

时间:2012-09-13 11:43:30

标签: java builder

将构建器实例存储在它构建的实例中是否被视为一种好的做法?问题是,当我需要为我已经拥有的对象创建一个非常类似的对象时,我经常发现自己。可推测此对象有许多8-10个字段。通常,对于一个可变对象,我会使用setter。

例如,让我们采用经典的布洛赫NutricionFacts示例:

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 Builder builder;

    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;

        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() {
            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;
        this.builder = builder;
    }
}

我已经修改了一下,所以如果我想在将来制作一个类似的副本,我可以访问构建器实例吗?

您怎么看?

1 个答案:

答案 0 :(得分:6)

如果重复使用Builder构建第二个实例,会发生什么?然后,第一个实例中的Builder将生成与第二个实例类似的实例。可能不是你所期望的。

我建议使用模板实例创建Builder选项。

    public Builder(NutritionFacts template) {
        this.servingSize = template.getServingSize();
        ...
    }