Ответ
Паттерн Builder (Строитель) — это порождающий шаблон проектирования, который позволяет создавать сложные объекты пошагово, отделяя конструирование объекта от его представления. Он особенно полезен для объектов с большим количеством параметров, многие из которых являются необязательными.
Решаемая проблема
Избегание "телескопического конструктора" (множества перегруженных версий с разными наборами параметров) и необходимости передавать null для неиспользуемых полей.
Классическая реализация на Java
public class Computer {
// Обязательные параметры (final)
private final String cpu;
private final String ram;
// Необязательные параметры
private final String storage;
private final String gpu;
// Приватный конструктор, принимает Builder
private Computer(ComputerBuilder builder) {
this.cpu = builder.cpu;
this.ram = builder.ram;
this.storage = builder.storage;
this.gpu = builder.gpu;
}
// Статический вложенный класс Builder
public static class ComputerBuilder {
// Обязательные параметры
private final String cpu;
private final String ram;
// Необязательные параметры с значениями по умолчанию
private String storage = "256GB SSD";
private String gpu = "Integrated";
// Конструктор Builder с обязательными параметрами
public ComputerBuilder(String cpu, String ram) {
this.cpu = cpu;
this.ram = ram;
}
// Методы для установки необязательных параметров (возвращают this для fluent API)
public ComputerBuilder storage(String storage) {
this.storage = storage;
return this;
}
public ComputerBuilder gpu(String gpu) {
this.gpu = gpu;
return this;
}
// Финальный метод build() создает целевой объект
public Computer build() {
// Здесь можно добавить валидацию параметров
if (cpu == null || ram == null) {
throw new IllegalArgumentException("CPU and RAM are required");
}
return new Computer(this);
}
}
}
// Использование (Fluent Interface):
Computer myPC = new Computer.ComputerBuilder("Intel i7", "16GB DDR4")
.storage("1TB NVMe")
.gpu("NVIDIA RTX 4070")
.build(); // Создается неизменяемый объект Computer
Ключевые преимущества
- Читаемость и ясность: Имена методов (
storage(),gpu()) делают код самодокументируемым. - Гибкость: Позволяет создавать объекты с разными комбинациями параметров, не загромождая класс множеством конструкторов.
- Неизменяемость (Immutability): Целевой объект (
Computer) может быть сделан неизменяемым (finalполя), что повышает надежность в многопоточных средах. - Валидация: Проверку корректности параметров можно централизованно выполнить в методе
build()перед созданием объекта.
Альтернативы в современном Java
- Lombok
@Builder: Генерирует код Builder автоматически. - Record с Builder (в комбинации с библиотеками): Для создания неизменяемых DTO.