Effective Java笔记:当遇到多个构造器参数时,考虑用构建器

我们考虑一种情况,在一个类初始化时,我们要构造多个参数时,毫无疑问,我们可以这样做:

1
2
3
4
5
6
7
8
9
10
11
12
13
public class BuildPattern{
private int a;
private int b;
private int c;
private int d;
public BuildPattern(int a,int b,int c,int d){
this.a = a;
this.b = b;
this.c = c;
this.d = d;
}
}

但是,如果c 和 d 是可选参数,我们并不想在构造器中将默认值传入,改怎么做呢?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class BuildPattern{
private int a;
private int b;
private int c;
private int d;
public BuildPattern(int a,int b){
this.a = a;
this.b = b;
this.c = 0;
this.d = 0;
}
public BuildPattern(int a,int b,int c){
this.a = a;
this.b = b;
this.c = c;
this.d = 0;
}
public BuildPattern(int a,int b,int c,int d){
this.a = a;
this.b = b;
this.c = c;
this.d = d;
}
}

三四个参数还好说,但是参数越来越多的时候,就变得很难管理了。我们也很容易想到重叠构造器模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class BuildPattern{
private int a;
private int b;
private int c;
private int d;
public BuildPattern(int a,int b){
this(a,b,0);
}
public BuildPattern(int a,int b,int c){
this(a,b,c,0);
}
public BuildPattern(int a,int b,int c,int d){
this.a = a;
this.b = b;
this.c = c;
this.d = d;
}
}

此时的重叠构造器模式在参数越来越多的时候也会变的难以管理,于是想到了另一种替代颁发,JavaBean模式

1
2
3
4
5
6
7
8
9
10
11
12
13
public class BuildPattern{
private int a = -1;//必须参数,没有初始化值
private int b = -1;
private int c = 0;
private int d = 0;
public BuildPattern(){}
public void setA(int val){a = val;}
public void setB(int val){b = val;}
public void setC(int val){c = val;}
public void setD(int val){d = val;}
}

此时创建实例就容易多了,代码也容易阅读:

1
2
3
4
BuildPattern bp = new BuildPattern();
bp.setA(3);
bp.setB(4);
bp.setC(5);

不过,因为构造过程被分到了几个调用中,在调用过程中可能出现不一致的状态,即线程不安全。于是我们有了另一种解决以上问题的办法:我们不值接生成想要的对象,而是让客户端利用所有必要的参数调用构造器,从而得到一个builder对象,在具体实现中调用类似setter的方法,来设置每个可选的相关参数。范例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
public class BuilderPattern {
private final int a;
private final int b;
private final int c;
private final int d;
public static class Builder{
//必选参数
private final int a;
private final int b;
//可选参数
private int c = 0;
private int d = 0;
public Builder(int tempA,int tempB){
this.a = tempA;
this.b = tempB;
}
public Builder c(int val){
c = val;
return this;
}
public Builder d(int val){
d = val;
return this;
}
public BuilderPattern build(){
return new BuilderPattern(this);
}
}
public BuilderPattern(Builder builder) {
a = builder.a;
b = builder.b;
c = builder.c;
d = builder.d;
}
public void show(){
System.out.println("a="+a);
System.out.println("b="+b);
System.out.println("c="+c);
System.out.println("d="+d);
}
public static void main(String[] args) {
BuilderPattern bp = new BuilderPattern.Builder(1, 2).c(3).d(4).build();
bp.show();
}
}
0%