遇到多个构造器参数时要考虑用构建器
2016-06-24 本文已影响186人
想飞的僵尸
第二条:遇到多个构造器参数时要考虑用构建器。
1. 什么是构建器?
顾名思义,构建器就是用来构建一个类用的,具体做法我们来看代码:
public class BuilderObject {
private final String filed01;
private final String filed02;
private final String filed03;
private final String filed04;
private BuilderObject(Builder builder){
this.filed01 = builder.filed01;
this.filed02 = builder.filed02;
this.filed03 = builder.filed03;
this.filed04 = builder.filed04;
}
//构建器(内部类)
public static class Builder{
private String filed01;
private String filed02;
private String filed03;
private String filed04;
public Builder filed01(String filed01){
this.filed01 = filed01;
return this;
}
public Builder filed02(String filed02){
this.filed02 = filed02;
return this;
}
public Builder filed03(String filed03){
this.filed03 = filed03;
return this;
}
public Builder filed04(String filed04){
this.filed04 = filed04;
return this;
}
public BuilderObject build(){//build方法,生成一个需要被构建的类
return new BuilderObject(this);
}
}
}
使用的时候就像这样:
BuilderObject builderObject = new BuilderObject.Builder()
.filed01("filed01")
.filed02("filed02")
.filed03("filed03")
.filed04("filed04")
.build();
2. 在什么时候我们应该使用构建器呢?
如果有这样一个类:
public class MyObject {
private String filed01; //必填
private String filed02; //选填
private String field03; //选填
}
那么我们会怎样写它的构造器呢?
这样?
public MyObject(String filed01, String filed02, String field03) {
this.filed01 = filed01;
this.filed02 = filed02;
this.field03 = field03;
}
public MyObject(String filed01, String filed02) {
this(filed01, filed02, null);
}
public MyObject(String filed01) {
this(filed01, null, null);
}
还是说用静态工厂方法来替代构造器?
上面有三个字段还好,要是有跟多的字段呢?很明显用多个构造器或是多个静态工厂方法都是不科学的。
这时候有人可能会说,用Javabean方式不就可以了么?像下面这样:
public class MyObject {
private String filed01; //必填
private String filed02; //选填
private String field03; //选填
public MyObject(String filed01) {
this.filed01 = filed01;
}
public void setField03(String field03) {
this.field03 = field03;
}
public void setFiled02(String filed02) {
this.filed02 = filed02;
}
}
使用的时候就可以像这样:
MyObject myObject = new MyObject("filed01");
myObject.setFiled02("filed02");
myObject.setFiled03("filed03");
哇哦!问题好像完美解决了,所以构建器什么的是没有卵用的。(做梦吧!)
javabean模式有一个致命的缺陷,就是它的构造过程分部到几次调用中,而不是一次性完成的。这意味着什么呢?意味着它有可能在构造的过程中被改变,这一点在多线程、高并发的程序中显得尤为重要。
不仅如此,javabean模式还有第二个缺点:如果对象中含有final修饰的字段,那么javabean模式将不能对其执行setter操作。对于这个问题构建器方式完美解决了,就想前文给出的示例一样。
总结
如果类的构造器或是静态工厂方法中具有多个参数,设计这种类时,使用Builder方式(构建器方式)就是种不错的选择,特别是当大多是参数都是可选的时候。与使用传统的重叠构造器模式相比,使用Builder模式的客户端代码将更容易阅读和编写,构建器也比javabean更加安全。