Effective Java 学习笔记《二》 构建器

来源:互联网 发布:剑与家园 知乎 编辑:程序博客网 时间:2024/05/19 05:01

遇到多个构造器参数时可以使用构建器

这一节一看就是我需要的,以前在cl工作时常常以后构造器要写20多个参数,好在IDE好用,不然调用构造器时参数真要一个一个对,很麻烦。

当然,除了写所谓的“重叠构造器”之外,可以用javaBeans模式,写一个无参构造器搭配所有的set方法。但是这个模式据书上所说有很大的缺点:构造过程被分到到了几个调用中,在构造过程中JavaBean可能处于不一致的状态,若试图使用处于不一致状态的对象,将会导致失败,而且很难调试。并且线程不安全。

那到底应该怎么办呢?

答案来了

Builder模式
*在Java的应用中JavaMail使用到了该模式。

package study.patterns.builder;/** * Builder模式,用于大量可选参数对象的构建(大于4个或内部属性经常扩展) * @author qbg * 不可变类 */public class NutritionFacts {    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 servings;        //可选参数        private int calories = 0;        private int fat = 0;        private int sodium = 0;        private int carbohydrate = 0;        public Builder(int servings){            this.servings = servings;        }        public Builder calories(int cal){            calories = cal;            return this;        }        public Builder fat(int fat){            this.fat = fat;            return this;        }        public Builder sodium(int sod){            this.sodium = sod;            return this;        }        public Builder carbohydrate(int car){            this.carbohydrate = car;            return this;        }        public NutritionFacts build(){            return new NutritionFacts(this);        }    }    /*     *私有化构造器,创建该对象只能通过构建器      */    private NutritionFacts(Builder builder){        servings = builder.servings;        calories = builder.calories;        fat = builder.fat;        sodium = builder.sodium;        carbohydrate = builder.carbohydrate;    }    public void print(){        System.out.println("servings:"+servings);        System.out.println("calories:"+calories);        System.out.println("fat:"+fat);        System.out.println("sodium:"+sodium);        System.out.println("carbohydrate:"+carbohydrate);    }    public static void main(String[] args) {        NutritionFacts cocaCola = new NutritionFacts.Builder(600).calories(20)                .carbohydrate(300).build();        System.out.println("可口可乐营养成分:");        cocaCola.print();    }}

不直接生成想要的对象,而是让客户端利用所有必要的参数调用构造器,得到一个builder对象,然后在builder对象上调用类似于setter的方法,来设置可选参数。最后客户端调用无参的builder方法生成不可变的对象,这个builder是它构建的类的静态成员。

构建器适用于3个以上参数,尤其是有大多数参数可选的情况。比JavaBeans模式更加安全。

0 0