builder设计模式学习笔记

在面向对象编程过程中,通常通过构造器new的方式来获取一个类的对象。这种方式比较适合对象属性较少的情形。当对象的属性过多时,这种方式就不太适合了。以一个食物商品为例,它拥有总脂肪量,胆固醇,钠,蔗糖等20多个属性,当我们生成该商品的对象时,有些属性并不需要,于是我们会以重叠构造器的方式来编写这个类。

public class Food01 {

    private final int servingSize;

    private final int serving;

    private int calories = 0;

    private int fat = 0;

    private int sodium = 0;

    private int carbohydrate = 0;

    public Food01(int servingSize){
        this(servingSize,0);
    }

    public Food01(int servingSize,int serving){
        this(servingSize,serving,0);
    }

    public Food01(int servingSize,int serving,int calories){
        this(servingSize,serving,calories,0);
    }

    public Food01(int servingSize,int serving,int calories,int fat){
        this(servingSize,serving,calories,fat,0);
    }

    public Food01(int servingSize,int serving,int calories,int fat,int sodium){
        this(servingSize,serving,calories,fat,sodium,0);
    }

    public Food01(int servingSize,int serving,int calories,int fat,int sodium,int carbohydrate){
        this.servingSize = servingSize;
        this.serving = serving;
        this.calories = calories;
        this.fat = fat;
        this.sodium = sodium;
        this.carbohydrate = carbohydrate;
    }
}

代码中只列举了六个属性,当属性20多个时,以这种方式生成对象,将会导致代码庞大且难以编写和阅读。对于这种情况还有一种方式可以替代,就是通过javaBeans模式,通过set和get方法来设置对象的属性,避免了大量的构造器。

Food food = new Food();
food.setServingSize(servingSize);
food.setServing(serving);
food.setcalories(calories);

javaBeans模式虽然解决了重叠构造器所遇到的问题,但是它有一个严重的缺点。它将所需属性的对象的生成分成了好几步完成,在food对象set属性时可能会遭遇多线程问题,这需要程序员编写额外代码来保证线程安全。采用Builder模式就可以解决前面两种方式遇到的问题。
Builder模式是在采用静态内部类Builder,通过该静态内部类调用类似setter的方法来设置属性,在通过build方法生成所需的对象。具体代码如下:

public class Food {
    private final int servingSize;
    private final int serving;
    private final int calories;
    private final int fat;
    private final int sodium;
    private final int carbohydrate;

    private Food(Builder builder) {
        serving = builder.serving;
        servingSize = builder.servingSize;
        calories = builder.calories;
        fat = builder.fat;
        sodium = builder.sodium;
        carbohydrate = builder.carbohydrate;

    }

    public int getCalories() {
        return calories;
    }

    static class Builder{
        private final int servingSize;
        private final int serving;

        private int calories = 0;
        private int fat = 0;
        private int sodium = 0;
        private int carbohydrate = 0;

        public Builder(int servingSize,int serving) {
            this.servingSize = servingSize;
            this.serving = serving;
        }

        public Builder calories(int calories) {
            this.calories = calories;
            return this;
        }

        public Builder fat(int fat) {
            this.fat = fat;
            return this;
        }

        public Builder sodium(int sodium) {
            this.sodium = sodium;
            return this;
        }

        public Builder carbohydrate(int carbohydrate) {
            this.carbohydrate = carbohydrate;
            return this;
        }

        public Food build() {
            return new Food(this);
        }
    }


}

builder的每一个setter方法都返回builder本身,用户可以调用不同的setter方法来设置所需的属性,最后将builder对象通过构造器的方式注入到Food对象,并将属性复制到Food对象。采用builder模式,代码就相对容易编写,且易于阅读。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值