← Назад к вопросам

Что такое телескопический конструктор?

1.0 Junior🔥 61 комментариев
#Основы Java

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Телескопический конструктор (Telescoping Constructor Pattern)

Телескопический конструктор — это паттерн, при котором в классе определяется несколько перегруженных конструкторов, каждый из которых вызывает другой конструктор с большим количеством параметров. Название происходит от того, что конструкторы как бы «вложены» друг в друга, подобно секциям телескопа.

Проблема: класс с множеством опциональных полей

Представьте, что нужно создать класс для пиццы с множеством параметров:

public class Pizza {
    private final String size;        // Обязательный
    private final String crust;       // Обязательный
    private final boolean cheese;     // Опциональный
    private final boolean pepperoni;  // Опциональный
    private final boolean ham;        // Опциональный
    private final boolean onion;      // Опциональный
    private final boolean mushroom;   // Опциональный
    
    // Конструктор со всеми параметрами
    public Pizza(String size, String crust, boolean cheese, 
                 boolean pepperoni, boolean ham, boolean onion, boolean mushroom) {
        this.size = size;
        this.crust = crust;
        this.cheese = cheese;
        this.pepperoni = pepperoni;
        this.ham = ham;
        this.onion = onion;
        this.mushroom = mushroom;
    }
}

// Использование - УЖАСНО
Pizza pizza = new Pizza("large", "thick", true, true, false, true, false);
// Что означают все эти boolean? Очень трудно понять

Решение: Телескопический конструктор

public class Pizza {
    private final String size;        // Обязательный
    private final String crust;       // Обязательный
    private final boolean cheese;     // Опциональный
    private final boolean pepperoni;  // Опциональный
    private final boolean ham;        // Опциональный
    private final boolean onion;      // Опциональный
    private final boolean mushroom;   // Опциональный
    
    // Конструктор с минимальными параметрами
    public Pizza(String size, String crust) {
        this(size, crust, false);
    }
    
    // Конструктор + cheese
    public Pizza(String size, String crust, boolean cheese) {
        this(size, crust, cheese, false);
    }
    
    // Конструктор + cheese + pepperoni
    public Pizza(String size, String crust, boolean cheese, boolean pepperoni) {
        this(size, crust, cheese, pepperoni, false);
    }
    
    // Конструктор + cheese + pepperoni + ham
    public Pizza(String size, String crust, boolean cheese, 
                 boolean pepperoni, boolean ham) {
        this(size, crust, cheese, pepperoni, ham, false);
    }
    
    // Конструктор + cheese + pepperoni + ham + onion
    public Pizza(String size, String crust, boolean cheese, 
                 boolean pepperoni, boolean ham, boolean onion) {
        this(size, crust, cheese, pepperoni, ham, onion, false);
    }
    
    // Полный конструктор
    public Pizza(String size, String crust, boolean cheese, 
                 boolean pepperoni, boolean ham, boolean onion, boolean mushroom) {
        this.size = size;
        this.crust = crust;
        this.cheese = cheese;
        this.pepperoni = pepperoni;
        this.ham = ham;
        this.onion = onion;
        this.mushroom = mushroom;
    }
    
    // Getters
    public String getSize() { return size; }
    public String getCrust() { return crust; }
    public boolean hasCheese() { return cheese; }
    public boolean hasPepperoni() { return pepperoni; }
    public boolean hasHam() { return ham; }
    public boolean hasOnion() { return onion; }
    public boolean hasMushroom() { return mushroom; }
}

// Использование
Pizza pizza1 = new Pizza("large", "thick");  // Без всех добавок
Pizza pizza2 = new Pizza("medium", "thin", true);  // Только cheese
Pizza pizza3 = new Pizza("large", "thick", true, true, true, false, true);

Проблемы телескопического конструктора

  1. Слишком много перегруженных конструкторов — код усложняется
  2. Сложно выбрать нужный конструктор — нужно помнить порядок параметров
  3. Легко ошибиться — может быть путаница в параметрах
  4. Масштабируемость — при добавлении новых полей нужно добавить новые конструкторы
  5. Читаемость — при создании объекта с множеством булевых параметров непонятно, что они означают

Лучшее решение: Builder паттерн

Builder — это более современный и удобный способ работать с объектами, имеющими множество опциональных параметров:

public class Pizza {
    private final String size;
    private final String crust;
    private final boolean cheese;
    private final boolean pepperoni;
    private final boolean ham;
    private final boolean onion;
    private final boolean mushroom;
    
    // Приватный конструктор
    private Pizza(PizzaBuilder builder) {
        this.size = builder.size;
        this.crust = builder.crust;
        this.cheese = builder.cheese;
        this.pepperoni = builder.pepperoni;
        this.ham = builder.ham;
        this.onion = builder.onion;
        this.mushroom = builder.mushroom;
    }
    
    // Builder класс
    public static class PizzaBuilder {
        // Обязательные параметры
        private final String size;
        private final String crust;
        
        // Опциональные параметры с значениями по умолчанию
        private boolean cheese = false;
        private boolean pepperoni = false;
        private boolean ham = false;
        private boolean onion = false;
        private boolean mushroom = false;
        
        // Конструктор Builder'а
        public PizzaBuilder(String size, String crust) {
            this.size = size;
            this.crust = crust;
        }
        
        // Методы для установки опциональных параметров
        public PizzaBuilder withCheese(boolean value) {
            this.cheese = value;
            return this;
        }
        
        public PizzaBuilder withPepperoni(boolean value) {
            this.pepperoni = value;
            return this;
        }
        
        public PizzaBuilder withHam(boolean value) {
            this.ham = value;
            return this;
        }
        
        public PizzaBuilder withOnion(boolean value) {
            this.onion = value;
            return this;
        }
        
        public PizzaBuilder withMushroom(boolean value) {
            this.mushroom = value;
            return this;
        }
        
        // Метод build для создания объекта
        public Pizza build() {
            return new Pizza(this);
        }
    }
    
    // Getters
    public String getSize() { return size; }
    public String getCrust() { return crust; }
    public boolean hasCheese() { return cheese; }
    // ... остальные getters
}

// Использование Builder'а - НАМНОГО ЛУЧШЕ!
Pizza pizza1 = new Pizza.PizzaBuilder("large", "thick")
    .build();  // Без добавок

Pizza pizza2 = new Pizza.PizzaBuilder("medium", "thin")
    .withCheese(true)
    .build();

Pizza pizza3 = new Pizza.PizzaBuilder("large", "thick")
    .withCheese(true)
    .withPepperoni(true)
    .withHam(true)
    .withMushroom(true)
    .build();

Сравнение подходов

// ТЕЛЕСКОПИЧЕСКИЙ КОНСТРУКТОР - плохо
Pizza pizza = new Pizza("large", "thick", true, true, false, true, false);
// Непонятно, что означают эти булевые значения

// BUILDER ПАТТЕРН - хорошо
Pizza pizza = new Pizza.PizzaBuilder("large", "thick")
    .withCheese(true)
    .withPepperoni(true)
    .withOnion(true)
    .build();
// Полностью ясно, какие добавки выбраны

Builder с Lombok (современный способ)

С помощью аннотации @Builder из Lombok можно автоматически генерировать Builder:

import lombok.Builder;
import lombok.Getter;

@Getter
@Builder
public class Pizza {
    private final String size;              // Обязательный по умолчанию
    private final String crust;             // Обязательный по умолчанию
    private final boolean cheese;           // Опциональный (false по умолчанию)
    private final boolean pepperoni;        // Опциональный
    private final boolean ham;              // Опциональный
    private final boolean onion;            // Опциональный
    private final boolean mushroom;         // Опциональный
}

// Использование
Pizza pizza = Pizza.builder()
    .size("large")
    .crust("thick")
    .cheese(true)
    .pepperoni(true)
    .onion(true)
    .build();

Итоги

  • Телескопический конструктор — это старый паттерн с множеством перегруженных конструкторов
  • Проблемы — код усложняется, становится трудно читать и масштабировать
  • Лучшее решение — использовать Builder паттерн
  • Современный подход — использовать @Builder из Lombok

Большинство современных проектов Java используют Builder вместо телескопических конструкторов, так как это делает код чище, понятнее и удобнее.

Что такое телескопический конструктор? | PrepBro