何时使用Builder构建器?

基于Builder实现可选参数创建对象

Posted by MasterJen on November 20, 2018

Hey Builder

Wealth is the test of a man’s character.–财富是对一个人品格的试金石.

大家都知道,静态工厂和构造器有个共同的局限性,就是它们不能很好地扩展到大量的可选参数,因此有什么办法实现呢?

那就是Builder模式,它既能保证像重叠构造器模式那样的安全性,也能像JavaBean那样有着良好的可读性,它的使用,就是不直接产生对象,而是让客户端利用所有必要的参数调用构造器,得到一个Builder对象,然后客户端zai builder对象上调用类似于setter的方法,来设置每个相关的参数,最后,客户端调用无参数的builder方法,来生产不可变得对象,这个builder就是它构建的类的静态成员类.

爱码如下:

public class NutritionFacts {
//    required 必选参数
    private final int servingSize;
    private final int servings;
//   可选参数
    private final int calories;
    private final int fat;
    private final int sodium;
    private final int color;

    @Override
    public String toString() {
        return "NutritionFacts{" +
                "servingSize=" + servingSize +
                ", servings=" + servings +
                ", calories=" + calories +
                ", fat=" + fat +
                ", sodium=" + sodium +
                ", color=" + color +
                '}';
    }
//    静态内部类  Builder构建器
    public static class Builder{
//        required
        private final int servingSize;
        private final int servings;
//        Optional 给出默认值
        private  int calories = 0;
        private  int fat = 0;
        private  int sodium = 0;
        private  int color = 0;
//        Builder 构造方法  含有必选参数
        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 color(int val){
            color = val;
            return this;
        }
         public NutritionFacts build(){
            return new NutritionFacts(this);
         }
    }
//    目标类的构造方法
    public NutritionFacts(Builder builder) {
        servingSize = builder.servingSize;
        servings = builder.servings;
        calories = builder.calories;
        fat = builder.fat;
        sodium = builder.sodium;
        color = builder.color;
    }

      public static void main(String[] args) {
//        测试 可选参数
        NutritionFacts nutritionFacts = new NutritionFacts(new Builder(240,90 ).calories(20).sodium(40).color(89));
          System.out.println(nutritionFacts.toString());
      }
}

测试结果:

    NutritionFacts{servingSize=240, servings=90, calories=20, fat=0, sodium=40, color=89}

是不是感觉很简单呢?