多个构造器参数时要考虑用构建器

来源:互联网 发布:淘宝怎么引流 编辑:程序博客网 时间:2024/06/07 04:02

当一个类有大量的可选属性是,要考虑用构建器替代构造器,构造器模式会让类的实例化变得太过复杂。

构建器可以见名之意,并且有很大的灵活性。

构建器构造对象不直接生成想要的对象,而是让客户端利用所有必要的参数调用构造器(或者静态工厂),

得到一个builder对象。然后客户端在builder对象上调用类似于setter的方法,来设置每个相关的可选参数。

最后,客户端调用无参的build方法来生成不可变的对象。这个builder是它构建的类的静态成员类。

示例:

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;    /**     * 这里必须用静态方法,否则在没有外部类的情况下无法新建内部类     */    public static class Builder {        //必选属性        private final int servingSize;        private final int servings;        //可选属性        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 carbohydrate(int val) {            carbohydrate = val;            return this;        }        public Builder sodium(int val) {            sodium = val;            return this;        }        public Builder fat(int val) {            fat = 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;    }    public String toString() {        return "[" + servingSize + "," + servings + "," + calories + "," + fat + "," + sodium + "," + carbohydrate + "]";    }}

public class Main {    public static void main(String[] args){        /**         * 初始化时,能够见名之意,并且可选属性可以连环赋值,避免了像setter方法一样需要很长的代码。         */        NutritionFacts nutritionFacts=new NutritionFacts.Builder(10,20).calories(30).sodium(35).build();        System.out.println(nutritionFacts.toString());    }}

[10,20,30,0,35,0]

阅读全文
0 0
原创粉丝点击