现象
最让人烦的构造器创建对象,而且在不同的场景,还需要写多个构造器
Task task = new Task(112, "紧急任务", "处理一下这个任务",
90, 3, 1, 36, "刘主管", 18, "客服1", "11, 12, 13",
"客服3, 客服4, 客服5", true, new Date(),
new Date(), new Date(), new Date(), new Date(),
0, "需要尽快完成", ...);
每个字段都看不到是个啥,可读性非常差
最基本的set方法都比这个容易读
Task task = new Task();
task.setId(112);
task.setName("紧急任务");
task.setContent("处理一下这个任务");
task.setParentId(90);
task.setType(3);
task.setLevel(1);
task.setAssignFromId(36);
task.setAssignFromName("刘主管");
task.setAssignTo(18);
但是set多了又会代码长,不优雅,无法判断是否可选,容易漏写
Builder解决
public class Task {
private long id;
private String name;
private String content;
private int type;
private int status;
private Date finishDate;
private Task(TaskBuilder taskBuilder) {
this.id = taskBuilder.id;
this.name = taskBuilder.name;
this.content = taskBuilder.content;
this.type = taskBuilder.type;
this.status = taskBuilder.status;
this.finishDate = taskBuilder.finishDate;
}
/**
* Builder(生产者)
*/
public static class TaskBuilder {
private long id;
private String name;
private String content;
private int type;
private int status;
private Date finishDate;
public TaskBuilder() {
}
public Task build(){
return new Task(this);
}
}
public long getId() {
return id;
}
public String getName() {
return name;
}
public String getContent() {
return content;
}
public int getType() {
return type;
}
public int getStatus() {
return status;
}
public Date getFinishDate() {
return finishDate;
}
@Override
public String toString() {
return "Task{" +
"id=" + id +
", name='" + name + '\'' +
", content='" + content + '\'' +
", type=" + type +
", status=" + status +
", finishDate=" + finishDate +
'}';
}
}
使用
Task task = new Task.TaskBuilder()
.type(1)
.content("处理一下这个任务")
.status(0)
.finishDate(new Date())
.build();
System.out.println(task);
Lombok中的Builder
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class TestLombok {
@Builder.Default
private String aa = "zzzz";
public static void main(String[] args) {
TestLombok build = TestLombok.builder().build();
System.out.println(build);
}
}
使用Builer时四个注解需要同时使用,不然没有无参构造方法等情况
默认值记得使用@Builder.Default
Java8中的Builder
public class GenericBuilder<T> {
private final Supplier<T> instantiator;
private List<Consumer<T>> instanceModifiers = new ArrayList<>();
public GenericBuilder(Supplier<T> instantiator) {
this.instantiator = instantiator;
}
public static <T> GenericBuilder<T> of(Supplier<T> instantiator) {
return new GenericBuilder<T>(instantiator);
}
public <U> GenericBuilder<T> with(BiConsumer<T, U> consumer, U value) {
Consumer<T> c = instance -> consumer.accept(instance, value);
instanceModifiers.add(c);
return this;
}
public T build() {
T value = instantiator.get();
instanceModifiers.forEach(modifier -> modifier.accept(value));
instanceModifiers.clear();
return value;
}
}
使用
private static void testJava8Builder() {
Java8Task java8Task = GenericBuilder.of(Java8Task::new)
.with(Java8Task::setId, 99L)
.with(Java8Task::setName, "紧急任务")
.with(Java8Task::setType, 1)
.with(Java8Task::setContent, "处理一下这个任务")
.with(Java8Task::setStatus, 0)
.with(Java8Task::setFinishDate, new Date())
.build();
System.out.println(java8Task);
}
链式
/**
* 基础分页请求类,如有新加参数请继承
*/
@Data
@Accessors(chain = true)
public class BasePagerReq {
/**
* 当前页,默认1
*/
private int concurrentPage = 1;
/**
* 当前页大小,默认15
*/
private int pageSize = 15;
}
使用
BasePagerReq basePagerReq = new BasePagerReq()
.setPageSize(1)
.setConcurrentPage(15);