高效Java02:构造方法参数较多时考虑使用构建器

假设某一业务场景(Scene)中有一个类,它有3个属性是必须的,另外还有20个属性是可选的。

重叠构造器

通常我们最先想到的是像下面这样创建一个类:

public class BusinessBean {
    private String requiredFiled1;
    private String requiredFiled2;
    private String requiredFiled3;
    private String optionalFiled1;
    private String optionalFiled2;

    // 省略剩下的可选域
    // ……

    public BusinessBean(String requiredFiled1, String requiredFiled2, String requiredFiled3) {
        this.requiredFiled1 = requiredFiled1;
        this.requiredFiled2 = requiredFiled2;
        this.requiredFiled3 = requiredFiled3;
    }

    public BusinessBean(String requiredFiled1, String requiredFiled2, String requiredFiled3, String optionalFiled1) {
        this(requiredFiled1, requiredFiled2, requiredFiled3);
        this.optionalFiled1 = optionalFiled1;
    }

    public BusinessBean(String requiredFiled1, String requiredFiled2, String requiredFiled3, String optionalFiled1, String optionalFiled2) {
        this(requiredFiled1, requiredFiled2, requiredFiled3, optionalFiled1);
        this.optionalFiled2 = optionalFiled2;
    }

    // 省略剩下的构造方法
    // ……

}

此处可选域多达20个,虽然可以照着这种方式继续编写,但对于客户端来说,调用代码会很难编写。

JavaBeans模式

除了上面的方式,我们可以使用第二种方法,即JavaBeans模式来编写,提供一个无参构造方法,然后调用setter方法设置需要的参数:

public class BusinessBean {
    private String requiredFiled1;
    private String requiredFiled2;
    private String requiredFiled3;
    private String optionalFiled1;
    private String optionalFiled2;

    // 省略剩下的可选域
    // ……

    public BusinessBean() {
    }

    public void setRequiredFiled1(String requiredFiled1) {
        this.requiredFiled1 = requiredFiled1;
    }

    public void setRequiredFiled2(String requiredFiled2) {
        this.requiredFiled2 = requiredFiled2;
    }

    public void setRequiredFiled3(String requiredFiled3) {
        this.requiredFiled3 = requiredFiled3;
    }

    public void setOptionalFiled1(String optionalFiled1) {
        this.optionalFiled1 = optionalFiled1;
    }

    public void setOptionalFiled2(String optionalFiled2) {
        this.optionalFiled2 = optionalFiled2;
    }

    // 省略剩下的setter方法
    // ……

}

Builder模式

上面第二种JavaBeans模式是我们最经常使用的,大部分场景下也能满足我们的需求,但仍有些情况无法满足我们的要求:

假设只有requiredFiled1=optionalFiled2才能满足我们某一子业务场景(subScene)需求,对象被创建出来(T1),对其完成判断(T2),然后执行业务场景subScene(T3),在T2至T3期间,对象的状态都有可能被调用setter方法而改变,从而处于不一致的状态,导致失败。

此时还有第三种方法供我们使用,这就是Builder模式,不直接生成对象,客户端先通过静态方法获取一个buider对象,然后在其上调用与上面第二种方法类似的setter方法设置相关参数,最后再由builder生成一个不可变对象:

public class BusinessBean {
    private String requiredFiled1;
    private String requiredFiled2;
    private String requiredFiled3;
    private String optionalFiled1;
    private String optionalFiled2;

    // 省略剩下的可选域
    // ……

    public static class Builder{
        private final String requiredFiled1;
        private final String requiredFiled2;
        private final String requiredFiled3;

        private String optionalFiled1;
        private String optionalFiled2;

        // 省略剩下的可选域
        // ……

        public Builder(String requiredFiled1, String requiredFiled2, String requiredFiled3){
            this.requiredFiled1 = requiredFiled1;
            this.requiredFiled2 = requiredFiled2;
            this.requiredFiled3 = requiredFiled3;
        }

        public Builder setOptionalFiled1(String optionalFiled1) {
            this.optionalFiled1 = optionalFiled1;
            return this;
        }

        public Builder setOptionalFiled2(String optionalFiled2) {
            this.optionalFiled2 = optionalFiled2;
            return this;
        }

        // 省略剩下的setter方法
        // ……

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

    private BusinessBean(Builder builder) {
        this.requiredFiled1 = builder.requiredFiled1;
        this.requiredFiled2 = builder.requiredFiled2;
        this.requiredFiled3 = builder.requiredFiled3;

        this.optionalFiled1 = builder.optionalFiled1;
        this.optionalFiled2 = builder.optionalFiled2;
        // 省略剩下的拷贝操作
        // ……
    }
}

客户端调用方法如下:

  BusinessBean businessBean = new BusinessBean.Builder("requiredValue1", "requiredValue2", "requiredValue3")
                .setOptionalFiled1("optionalFiledValue1").setOptionalFiled2("optionalFiledValue2").build();

这样客户端的代码就变得很简洁,其中builder的setter方法返回builder自身,形成链式编程,把所有setter都连接到一起。BusinessBean是不可变的,我们可以根据具体需要在builder中做一些校验,当所有参数都设置完毕后再通过build()方法将builder中数据拷贝到BusinessBean返回一个我们需要的对象实例。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值