Как сделать строитель для объекта
Короткий ответ
Строитель (builder) собирает объект по шагам. Это удобно, когда полей много и часть из них необязательна:
record Pizza(String size, boolean cheese, boolean mushrooms) {
static Builder builder() {
return new Builder();
}
static class Builder {
private String size = "medium";
private boolean cheese;
private boolean mushrooms;
Builder size(String size) { this.size = size; return this; }
Builder cheese() { this.cheese = true; return this; }
Builder mushrooms() { this.mushrooms = true; return this; }
Pizza build() {
return new Pizza(size, cheese, mushrooms);
}
}
}
void main() {
Pizza pizza = Pizza.builder().size("large").cheese().build();
IO.println(pizza);
}Результат:
Pizza[size=large, cheese=true, mushrooms=false]Каждый метод возвращает this, поэтому вызовы можно писать цепочкой.
Обязательные поля
Проверьте обязательные значения в build():
record Email(String to, String subject) {
static class Builder {
private String to;
private String subject = "(no subject)";
Builder to(String to) { this.to = to; return this; }
Builder subject(String subject) { this.subject = subject; return this; }
Email build() {
if (to == null) {
throw new IllegalStateException("recipient is required");
}
return new Email(to, subject);
}
}
}
void main() {
IO.println(new Email.Builder().to("anna@site.com").build());
new Email.Builder().subject("Hi").build();
}Результат:
Email[to=anna@site.com, subject=(no subject)]
Exception in thread "main" java.lang.IllegalStateException: recipient is requiredЧастая ошибка
Делать строитель для объекта с двумя-тремя полями. Строитель — это много кода; для маленьких объектов хватит записи с конструктором. А в библиотеке Lombok строитель генерирует аннотация @Builder.