Логотип YeaHub

База вопросов

Собеседования

Тренажёр

База ресурсов

Обучение

Навыки

Войти

Выбери, каким будет IT завтра — вместе c нами!

YeaHub — это полностью открытый проект, призванный объединить и улучшить IT-сферу. Наш исходный код доступен для просмотра на GitHub. Дизайн проекта также открыт для ознакомления в Figma.

© 2026 YeaHub

Документы

Медиа

Назад
Вопрос про JavaScript: Decorator pattern, design patterns, object-oriented programming, behavior extension

Как реализуется расширение поведения без модификации существующего кода?

Вопрос проверяет понимание паттерна проектирования 'Декоратор' и его применение для динамического добавления функциональности к объектам.

Короткий ответ

Паттерн 'Декоратор' позволяет динамически добавлять новое поведение объектам, не изменяя их исходный код. Он оборачивает исходный объект в объект-декоратор, который имеет тот же интерфейс и делегирует вызовы обёрнутому объекту, добавляя свою логику до или после. Это полезно, когда нужно расширить функциональность класса, но наследование не подходит из-за взрывного роста подклассов. Декоратор следует принципу открытости/закрытости: классы открыты для расширения, но закрыты для модификации.

Длинный ответ

Паттерн 'Декоратор' (Decorator) — это структурный паттерн проектирования, который позволяет динамически добавлять новую функциональность объектам, оборачивая их в специальные объекты-декораторы. Вместо изменения исходного класса (что нарушает принцип открытости/закрытости), вы создаёте цепочку обёрток, каждая из которых добавляет своё поведение.

Как это работает

Декоратор реализует тот же интерфейс, что и оборачиваемый объект. При вызове метода декоратор выполняет дополнительную логику (до или после) и затем делегирует вызов обёрнутому объекту. Это позволяет комбинировать поведение на лету, создавая гибкие конфигурации.

Пример на TypeScript

// Базовый интерфейс компонента
interface Coffee {
    cost(): number;
    description(): string;
}

// Конкретный компонент
class SimpleCoffee implements Coffee {
    cost() { return 5; }
    description() { return 'Simple coffee'; }
}

// Базовый декоратор
abstract class CoffeeDecorator implements Coffee {
    constructor(protected coffee: Coffee) {}
    cost() { return this.coffee.cost(); }
    description() { return this.coffee.description(); }
}

// Конкретные декораторы
class MilkDecorator extends CoffeeDecorator {
    cost() { return super.cost() + 2; }
    description() { return super.description() + ', milk'; }
}

class SugarDecorator extends CoffeeDecorator {
    cost() { return super.cost() + 1; }
    description() { return super.description() + ', sugar'; }
}

// Использование
let myCoffee: Coffee = new SimpleCoffee();
myCoffee = new MilkDecorator(myCoffee);
myCoffee = new SugarDecorator(myCoffee);
console.log(myCoffee.description()); // Simple coffee, milk, sugar
console.log(myCoffee.cost()); // 8

Где применяется

  • В UI-библиотеках для добавления стилей или поведения к компонентам (например, border, padding).
  • В потоковых API (Java I/O, .NET Streams) для добавления фильтров (буферизация, сжатие).
  • В middleware веб-фреймворков (Express.js, NestJS) для добавления логирования, аутентификации.

Вывод: Используйте паттерн 'Декоратор', когда нужно гибко добавлять обязанности объектам во время выполнения, избегая жёсткой иерархии наследования и сохраняя код чистым и расширяемым.

Уровень

  • Рейтинг:

    4

  • Сложность:

    5

Навыки

  • JavaScript

    JavaScript

  • TypeScript

    TypeScript

Ключевые слова

#Decorator pattern

#design patterns

#object-oriented programming

#behavior extension

Подпишись на Java Developer в телеграм