Sobes.tech
Назад к вопросам
Junior — Middle
57

Можешь привести пример применения паттерна декоратор в коде?

Компании, где спрашивали
РунитиРунити

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

sobes.tech AI

Что хотят услышать интервьюеры:

Паттерн декоратор нужен, чтобы динамически добавлять объекту новое поведение без изменения его класса. Обычно это делается через обёртку: базовый объект остаётся тем же, а дополнительные возможности подключаются снаружи. В Python это особенно удобно для расширения логики по шагам.

Определение:

Декоратор — это структурный паттерн, который позволяет «обернуть» объект другим объектом с тем же интерфейсом и добавить ему новое поведение. Вместо наследования используется композиция: объект передаётся в обёртку, а вызовы делегируются внутрь с добавлением нужной логики.

Пример использования:

Допустим, есть отправка уведомлений, и к базовой отправке нужно добавить логирование и шифрование без изменения основного класса.

from abc import ABC, abstractmethod


class Notifier(ABC):
    @abstractmethod
    def send(self, message: str) -> str:
        pass


class EmailNotifier(Notifier):
    def send(self, message: str) -> str:
        return f"Отправлено по email: {message}"


class NotifierDecorator(Notifier):
    def __init__(self, notifier: Notifier):
        self._notifier = notifier

    def send(self, message: str) -> str:
        return self._notifier.send(message)


class LoggingDecorator(NotifierDecorator):
    def send(self, message: str) -> str:
        print(f"[LOG] Отправка сообщения: {message}")
        return super().send(message)


class EncryptionDecorator(NotifierDecorator):
    def send(self, message: str) -> str:
        encrypted = f"encrypted({message})"
        return super().send(encrypted)


notifier = LoggingDecorator(EncryptionDecorator(EmailNotifier()))
result = notifier.send("Привет!")

print(result)

Пояснение кода:

  1. Notifier задаёт общий интерфейс с методом send.
  2. EmailNotifier — базовая реализация, которая просто отправляет сообщение.
  3. NotifierDecorator хранит ссылку на другой Notifier и делегирует ему вызов send.
  4. LoggingDecorator добавляет логирование перед основной отправкой.
  5. EncryptionDecorator изменяет сообщение, а затем передаёт дальше по цепочке.
  6. В notifier = LoggingDecorator(EncryptionDecorator(EmailNotifier())) декораторы складываются друг в друга, поэтому поведение наращивается поэтапно.

Ключевые моменты:

  • Декоратор добавляет поведение без изменения исходного класса.
  • Основа паттерна — одинаковый интерфейс у объекта и у обёртки.
  • Можно комбинировать несколько декораторов в цепочку.
  • Это гибче наследования, когда расширений много и они могут сочетаться.
  • В Python паттерн удобно реализуется через композицию объектов, а не через глубокую иерархию классов.