Назад к вопросам
Middle
80
questionbank

Что такое декоратор?

Sobes Copilot

Получайте ответы в реальном времени

Ответ от нейросети

sobes.tech AI

Декоратор — это структурный паттерн проектирования, который позволяет динамически добавлять новое поведение объектам, оборачивая их в специальные объекты-декораторы.

Основные принципы:

  • Композиция вместо наследования. Декоратор расширяет функциональность объекта, не изменяя его класса и не используя наследование.
  • Гибкость. Позволяет добавлять или удалять обязанности объекта во время выполнения.
  • Совместимость. Декораторы и оборачиваемые объекты имеют общий интерфейс, что позволяет использовать их взаимозаменяемо.

Структура:

  • Компонент (Component): Интерфейс для объектов, к которым можно динамически добавить новые обязанности.
  • Конкретный компонент (ConcreteComponent): Реализация Компонента.
  • Декоратор (Decorator): Абстрактный класс или интерфейс, который расширяет Компонент и содержит ссылку на объект Компонента.
  • Конкретные декораторы (Concrete Decorators): Реализации Декоратора, добавляющие конкретное поведение.

Пример (Python):

// Интерфейс компонента
class Coffee:
    def get_cost(self):
        pass

    def get_description(self):
        pass

// Конкретный компонент
class SimpleCoffee(Coffee):
    def get_cost(self):
        return 1.0

    def get_description(self):
        return "Simple Coffee"

// Базовый декоратор
class CoffeeDecorator(Coffee):
    def __init__(self, decorated_coffee):
        self._decorated_coffee = decorated_coffee

    def get_cost(self):
        return self._decorated_coffee.get_cost()

    def get_description(self):
        return self._decorated_coffee.get_description()

// Конкретный декоратор (Молоко)
class MilkDecorator(CoffeeDecorator):
    def get_cost(self):
        return self._decorated_coffee.get_cost() + 0.5

    def get_description(self):
        return self._decorated_coffee.get_description() + ", Milk"

// Использование
coffee = SimpleCoffee()
print(f"{coffee.get_description()}: ${coffee.get_cost()}") # Simple Coffee: $1.0

coffee_with_milk = MilkDecorator(coffee)
print(f"{coffee_with_milk.get_description()}: ${coffee_with_milk.get_cost()}") # Simple Coffee, Milk: $1.5

Преимущества:

  • Более гибкий способ расширения функциональности объектов, чем наследование.
  • Избегает разрастания субклассов, связанных с наследованием.
  • Позволяет добавлять несколько "слоев" поведения к одному объекту.

Недостатки:

  • Может усложнить код из-за большого количества мелких объектов.
  • Порядок оборачивания может иметь значение.

Применение в QA / Automation:

  • Добавление логирования к существующим методам без изменения их исходного кода.
  • Реализация обработки исключений для определенных вызовов.
  • Добавление тайминга или метрик производительности.
  • Использование библиотеками для автоматизации тестирования (например, в паттерне Page Object для добавления проверок или логирования при взаимодействии с элементами).