effecitve java 2 构建器

  1. 当一个类的参数有很多个的时候,有比较好构建方法
    1. 比如这个类有四个参数,可以使用几个构造器,其中一个参数的构造器调用两个参数的构造器,两个参数的构造器调用三个参数的构造器,三个的调用四个的,这种方式叫做重叠构造器
      package constructors.builder;
      
      public class NutritionFacts {
          private final int servingsSize;
          private final int servings;
          private final int calories;
          private final int fat;
          private final int sodium;
          private final int carbohydrate;
          public static class Builder{
              private final int servingSize;
              private final int servings;
              private int calories = 0;
              private int fat = 0;
              private int sodium = 0;
              private int carbohydrate = 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 sodium(int val){
                  sodium = val;
                  return  this;
              }
              public Builder carbohydrate(int val){
                  carbohydrate =  val;
                  return this;
              }
              public NutritionFacts build(){
                  return new NutritionFacts(this);
              }
          }
          private NutritionFacts(Builder builder){
              servingsSize = builder.servingSize;
              servings = builder.servings;
              calories = builder.calories;
              fat = builder.fat;
              sodium = builder.sodium;
              carbohydrate = builder.carbohydrate;
          }
      }
      

       

    2. 构建者模式
      1. 在A类里边定义一个静态内部类Builder
      2. Builder类拥有和A类一样多的成员变量
      3. 对于必填的成员变量,将其设置在Builder的构造函数中
      4. 对于不必要的成员变量,通过一些方法设置值,然后返回这个builder变量
      5. 在Builder类中写builder方法,这个方法创建了一个A类对象,构造器参数是Builder
      6. A类有一个参数是Builder的构造器,构造器的逻辑是将Builder的各个参数转换成自己的各个参数
            package constructors.builder;
        
            public class NutritionFacts {
                private final int servingsSize;
                private final int servings;
                private final int calories;
                private final int fat;
                private final int sodium;
                private final int carbohydrate;
                // Builder 是静态内部类
                public static class Builder{
                    // builder拥有和外部类一样的成员变量
                    private final int servingSize;
                    private final int servings;
                    private int calories = 0;
                    private int fat = 0;
                    private int sodium = 0;
                    private int carbohydrate = 0;
                    // 必要的参数作为Builder的过构造函数参数
                    public Builder(int servingSize, int servings){
                        this.servingSize  = servingSize;
                        this.servings  = servings;
                    }
                    // 其他参数作为具体的方法进行设置,最后返回builder对象
                    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 carbohydrate(int val){
                        carbohydrate =  val;
                        return this;
                    }
                    // builder方法构建一个外部类对象
                    public NutritionFacts build(){
                        return new NutritionFacts(this);
                    }
                }
                // builder类参数的构造函数,用于参数转化
                private NutritionFacts(Builder builder){
                    servingsSize = builder.servingSize;
                    servings = builder.servings;
                    calories = builder.calories;
                    fat = builder.fat;
                    sodium = builder.sodium;
                    carbohydrate = builder.carbohydrate;
                }
            }
        

         

      7. 接下来是一个比较复杂的例子,抽象类结构中的构建者模式
        1. 父类中维护了一个集合,
        2. 父类中有一个抽象的Builder类,这个Builder也有一个集合,是用来最后转换为外部类的,并且有向这个集合里添加元素的方法
        3. 父类的Builder类中还有一个self方法,这个self方法在父类的添加元素中被调用,可以返回子类的builder对象
        4. 父类的Builder中有builder方法,是抽象类,子类中重写这个方法,返回子类builder对应的外部类类型
          package constructors.builder;
          
          import java.util.EnumSet;
          import java.util.Objects;
          import java.util.Set;
          
          public abstract class Pizza {
              public enum Topping{
                  HAM,MUSHROOM,ONLON,PRPPER,SAUSAGE
              }
              // 父类维护了一个集合
              final Set<Topping> toppings;
              abstract static class Builder<T extends Builder<T>>{
                  EnumSet<Topping> toppings = EnumSet.noneOf(Topping.class);
                  // 父类的Builder中有向集合添加元素的方法
                  public T addTopping(Topping topping){
                      toppings.add(Objects.requireNonNull(topping));
                      return self();
                  }
                  // build和self方法是抽象的,留给子类去实现
                  abstract Pizza build();
                  protected abstract T self();
              }
              // 转换成员变量构造函数
              Pizza(Builder<?> builder){
                  toppings = builder.toppings.clone();
              }
          }
          
          package constructors.builder;
          
          import java.util.Objects;
          
          public class NyPizza extends Pizza {
              public enum Size {SMALL, MEDIUM, LARGE}
              private final Size size;
              public static class Builder extends Pizza.Builder<Builder>{
                  private final Size size;
                  // 子类自己的构造函数,用于子类自己特有成员赋值
                  public Builder(Size size){
                      this.size = Objects.requireNonNull(size);
                  }
          
                  // 这两个重写的方法,都是用于返回自理自己的builder对象和外部类对象
                  @Override
                  Pizza build() {
                      return new NyPizza(this);
                  }
          
                  @Override
                  protected Builder self() {
                      return this;
                  }
              }
              private NyPizza(Builder builder){
                  super(builder);
                  size = builder.size;
              }
          }
          
          package constructors.builder;
          
          public class Calzone extends Pizza {
              private final boolean sauceInside;
          
              // Builder是Pizza的内部类
              public static class Builder extends Pizza.Builder<Builder>{
                  private boolean sauceInside = false;
                  // 子类builder构造函数,用于子类特有成员变量赋值
                  public Builder sauceInside(){
                      sauceInside = true;
                      return  this;
                  }
          
                  @Override
                  Pizza build() {
                      sauceInside = true;
                      return new Calzone(this);
                  }
          
                  @Override
                  protected Builder self() {
                      return this;
                  }
              }
              private Calzone(Builder builder){
                  super(builder);
                  sauceInside =  builder.sauceInside;
              }
          }
          

           

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值