对付多参的构建,特别是一些必选,一些可选的时候我们一般有如下的解决办法。
比如抽象一个装机的类, cpu,内存,主板,硬盘是必选的,但是显卡,声卡,固态硬盘是可选的。
为了对付各种各样的装机需求。我们一般有如下办法:
1. 重载构造器
这样可能会需要多个构造器,可读性不好。
2. 用JavaBean模式的set方法。
这种可读性要好很多,但是其能够在运行期间随意的修改,不能够保持状态,不能够通过对构造参数的校验来避免问题,并且还会给线程同步带来麻烦。
3. 就是使用构建器了,看如下的代码:
public class Computer {
private String cpu;
private String mainBoard;
private String hardDisk;
private String memory;
private String solidDisk;
private String videoCard;
private String soundCard;
public static class Builder{
private String cpu;
private String mainBoard;
private String hardDisk;
private String memory;
// options
private String solidDisk;
private String videoCard;
private String soundCard;
public Builder(String cpu, String mainBoard, String hardDisk, String memory) {
this.cpu = cpu;
this.mainBoard = mainBoard;
this.hardDisk = hardDisk;
this.memory = memory;
}
public Builder solidDisk(String solidDisk){
this.solidDisk = solidDisk;
return this;
}
public Builder videoCard(String videoCard){
this.videoCard = videoCard;
return this;
}
public Builder soundCard(String soundCard){
this.soundCard = soundCard;
return this;
}
public Computer build(){
return new Computer(this);
}
}
public Computer(Builder builder){
this.cpu = builder.cpu;
this.mainBoard = builder.mainBoard;
this.hardDisk = builder.hardDisk;
this.memory = builder.memory;
this.solidDisk = builder.solidDisk;
this.soundCard = builder.soundCard;
this.videoCard = builder.videoCard;
}
}
这样Computer可以用如下的代码构造:
Computer computer = new Computer.Builder("7777", "huasuo", "rili", "kingston").solidDisk("sunsong").build();
这样带来的好处为
1. 既能想构造器那样安全,又能有比较好的可读性,如solidDisk一看就知道是给固态硬盘来赋值的。
2. 让可选参数返回builder本身,还模拟了具名参数,更加可读
3. 可以加入更多的校验
4. 更容易扩展,如果增加了新的参数,只需要新增一个方法,而不是新增n个构造器