对付多参的构建,特别是一些必选,一些可选的时候我们一般有如下的解决办法。
比如抽象一个装机的类, 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个构造器