Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Как сделать строитель для объекта

Короткий ответ

Строитель (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.

Функции из этого ответа

  • record — Объявляет запись — неизменяемый класс для хранения данных с готовыми equals(), hashCode() и toString().
  • static — Делает поле или метод общим для всего класса, а не для отдельного объекта.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.