Gymterview
junior

Что такое паттерн Decorator?

Decorator – паттерн, динамически добавляющий объекту новую функциональность, оборачивая его. Альтернатива наследованию через композицию.

Аналогия из жизни: Decorator – как топпинги к кофе. Базовый эспрессо можно “обернуть” молоком (латте), сиропом, взбитыми сливками – каждый слой добавляет что-то новое, не меняя сам кофе.

Пример
// Классический пример -- java.io
InputStream raw = new FileInputStream("data.txt");
InputStream buffered = new BufferedInputStream(raw);           // декоратор: буферизация
InputStream gzip = new GZIPInputStream(buffered);              // декоратор: распаковка
Reader reader = new InputStreamReader(gzip, StandardCharsets.UTF_8); // декоратор: символьный поток
Собственный Decorator
interface Logger {
    void log(String message);
}

class ConsoleLogger implements Logger {
    public void log(String message) { System.out.println(message); }
}

class TimestampLogger implements Logger {  // декоратор
    private final Logger wrapped;
    TimestampLogger(Logger wrapped) { this.wrapped = wrapped; }

    public void log(String message) {
        wrapped.log("[" + Instant.now() + "] " + message);
    }
}

class UpperCaseLogger implements Logger {  // декоратор
    private final Logger wrapped;
    UpperCaseLogger(Logger wrapped) { this.wrapped = wrapped; }

    public void log(String message) { wrapped.log(message.toUpperCase()); }
}

// Комбинирование декораторов
Logger logger = new TimestampLogger(new UpperCaseLogger(new ConsoleLogger()));
logger.log("hello"); // [2026-04-22T10:00:00Z] HELLO

Decorator vs Proxy vs Adapter

Критерий Decorator Proxy Adapter
Цель Добавить функциональность Контролировать доступ Преобразовать интерфейс
Интерфейс Тот же, что у обёртки Тот же, что у обёртки Другой (целевой)
Пример в JDK BufferedInputStream Proxy.newProxyInstance() Arrays.asList()

Частые ошибки

  • Слишком глубокая вложенность – 5+ декораторов усложняют отладку (длинный стек-трейс)
  • Путать Decorator и Proxy – Decorator добавляет функциональность, Proxy контролирует доступ

Как используется в 2026

  • java.io (streams), Collections.unmodifiable*(), Collections.synchronized*()
  • Spring: HandlerInterceptor, Filter – по сути декораторы HTTP-обработки

На собеседовании: назовите java.io как каноничный пример Decorator в JDK – это покажет понимание стандартной библиотеки. Частая ошибка – не уметь объяснить разницу между Decorator и Proxy.