Ответ
public class User {
private final String firstName;
private final String lastName;
private final int age;
private User(Builder builder) {
this.firstName = builder.firstName;
this.lastName = builder.lastName;
this.age = builder.age;
}
public static class Builder {
private String firstName;
private String lastName;
private int age;
public Builder firstName(String firstName) {
this.firstName = firstName;
return this;
}
public Builder lastName(String lastName) {
this.lastName = lastName;
return this;
}
public Builder age(int age) {
this.age = age;
return this;
}
public User build() {
return new User(this);
}
}
}
// Использование:
User user = new User.Builder()
.firstName("John")
.lastName("Doe")
.age(30)
.build();
Паттерн Builder позволяет создавать объекты с большим количеством параметров, делая код читаемым и избегая "телескопических конструкторов". Особенно полезен, когда некоторые параметры необязательны.
Ответ 18+ 🔞
Смотри, вот этот паттерн Builder — это вообще спасение, когда у тебя объект с параметрами, как у этого User: имя, фамилия, возраст. Представь, что их будет не три, а, блядь, десять, да ещё и половина опциональных. Что делать? Писать конструктор на десять параметров? Да это же пиздец просто, там при вызове всё перепутаешь, глаза сломаешь, пока поймёшь, где что. Это и есть тот самый "телескопический конструктор", про который умные дядьки говорят — хуйня полная.
А вот Builder решает это элегантно, ёпта. Смотри, как тут: у нас есть статический вложенный класс Builder. Он внутри себя копит все эти поля: firstName, lastName, age. И на каждый сеттер он возвращает сам себя — this. Это гениально, потому что можно вызывать методы цепочкой, как поезд.
Вот смотри на использование в конце: new User.Builder().firstName("John").lastName("Doe").age(30).build(); Красота же! Читается, как предложение: "Создай билдер, задай имя Джон, задай фамилию Доу, задай возраст тридцать, собери". Никакой путаницы. Хочешь задать только имя и возраст? Без проблем: .firstName("John").age(30).build(). Остальное будет null или 0, но ты явно видишь, что ты задал, а что пропустил. Доверия к такому коду — овердохуища.
И главная фишка в методе build(). Он, сука, создаёт итоговый объект User, передавая в его приватный конструктор самого себя — this. А конструктор User просто берёт из билдера все накопленные поля. Всё изолированно, красиво, объект после создания immutable (неизменяемый), если поля final, как тут. Хуй кто его сломает.
Так что если видишь, что параметров у объекта становится многовато, или они опциональные — сразу думай про Builder. Сэкономит кучу нервов тебе и тому, кто будет читать твой код после. А то без него получится пиздопроебибна с конструкторами на все случаи жизни.