Порождающие (Singleton, Builder)
Порождающие паттерны решают вопрос «как создать объект», когда простой new не справляется. Два самых частых в Java — Singleton и Builder.
Singleton — гарантирует, что у класса есть только один экземпляр на всё приложение:
class Config {
private static final Config INSTANCE = new Config();
private Config() {} // конструктор закрыт — снаружи new не вызвать
static Config getInstance() { return INSTANCE; }
}
Config.getInstance(); // всегда один и тот же объект
Builder — собирает сложный объект пошагово, когда у конструктора было бы слишком много параметров:
User user = User.builder()
.name("Артур")
.age(25)
.email("artur@mail.ru")
.build();
Копнуть глубже
Зачем Builder, а не просто конструктор с кучей параметров. Конструктор с 6+ параметрами одного типа (int, int, String, String) легко перепутать местами — компилятор не подскажет. Builder даёт именованные шаги, читается как предложение, и необязательные параметры можно просто не указывать:
// плохо — что есть что?
new User("Артур", 25, "Москва", null, true, false);
// хорошо — явно
User.builder().name("Артур").age(25).city("Москва").build();
В Java Builder часто генерируют автоматически — Lombok-аннотация @Builder пишет весь шаблонный код за тебя, не нужно писать вручную.
Где встречается Singleton на практике. Spring Bean по умолчанию одиночка (scope = singleton) — на всё приложение создаётся один объект сервиса, а не новый на каждый запрос. Это самая частая форма Singleton в реальном Java-коде, и Spring управляет этим за тебя — отдельно писать private static final INSTANCE почти никогда не нужно.
• почему Builder удобнее конструктора с многими параметрами (если дошёл до 2-го слоя).