effective java 当构造方法参数过多时使用 builder 模式的理解

本文探讨了Java Builder模式在面对构造方法参数过多时的应用,重点介绍了如何通过`return this`简化设置过程,并强调了Builder模式带来的对象不可变性和一致性优势,同时对比了JavaBeans模式的不足之处。
摘要由CSDN通过智能技术生成

java builder 模式

在effactive java上看到说当构造方法参数过多时使用builder模式,然后发现提供的set模板的Builder只需要return this。所以想了解一下细节以及差异。

JavaBeans模式本身有严重的缺陷。由于构造方法被分割成多次调用,所以在构造过程中JavaBean可能处于不一致状态。该类仅有通过检查构造函数参数的有效性,而没有强制的一致性措施。在不一致的状态下尝试使用对象可能导致一些错误,这些错误与平时代码的BUG很是不同,因此很难调试。一个相关的缺点是,javaBeans模式排除了让类不可变的可能性,并且需要程序员增加工作以确保线程安全。

在使用javaBean的时候,尤其是多线程获取的时候,几个线程对同一个javaBean操作:
线程A:对对象进行set操作。
线程B:对对象进行get操作。
这就会出现一种情况,线程A没有set完线程B就开始去相应属性。

Builder 模式

不直接构造所需的对象,而是调用一个包含所有必需参数的构造方法(或静态工厂)得到一个builder对象,然后设置可选参数,最后通过builder对象的一个无参builder方法来生成对象,该对象通常是不可变的。Builder通常是它所构建的雷达静态成员类。

//Builder Pattern 
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;

    private NutritionFacts(Builder builder) {
        servingSize = builder.servingSize;
        servings = builder.servings;
        calories = builder.calories;
        fat = builder.fat;
        sodium = builder.sodium;
        carbohydrate = builder.carbohydrate;
    }

    public static class Builder { // Required parameters 
        private final int servingSize;
        private final int servings;
        // Optional parameters - initialized to default values 
        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);
        }
    }
}

也可以用lombok的@Builder构造一个实例,属性不需要单独set。

Java return this

将方法的返回值类型指定为当前 Class ,那么,在方法体的最后可以直接 return this ,从而可以形成一个类似于 Builder Patern 的效果。但是依然会存在不一致性的问题。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值