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

Объясните концепцию фабрики декораторов и как она применяется в проектировании систем.

Компании, где спрашивали
Soft Media Group
Фабрика РешенияФабрика Решения

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

sobes.tech AI

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

Фабрика декораторов — это способ параметризовать декоратор и создавать его экземпляры под конкретную задачу. Такой подход позволяет переиспользовать один и тот же механизм обёртки для разных условий, не дублируя код. В проектировании систем это помогает отделять сквозную логику от бизнес-логики и делать поведение функций гибко настраиваемым.

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

Фабрика декораторов — это функция, которая принимает параметры и возвращает декоратор. Сам декоратор уже получает целевую функцию, оборачивает её и добавляет нужное поведение. Идея в том, что сначала задаются настройки, а потом создаётся конкретный декоратор под эти настройки.

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

Например, в сервисе нужно логировать выполнение разных операций с разным уровнем детализации. Вместо нескольких почти одинаковых декораторов можно сделать одну фабрику, которая принимает имя события и уровень логирования.

from functools import wraps

def log_event(level):
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            print(f"[{level}] Entering {func.__name__}")
            result = func(*args, **kwargs)
            print(f"[{level}] Leaving {func.__name__}")
            return result
        return wrapper
    return decorator


@log_event("INFO")
def create_user(name):
    return f"User {name} created"


@log_event("DEBUG")
def delete_user(user_id):
    return f"User {user_id} deleted"

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

Код показывает три уровня вложенности.
Сначала log_event(level) принимает параметр level и возвращает функцию decorator.
Затем decorator(func) получает исходную функцию и создаёт wrapper, который выполняет дополнительную логику до и после вызова func.
Декоратор @log_event("INFO") сначала вызывает фабрику с аргументом "INFO", а уже результат этой фабрики применяется к create_user.
@wraps(func) сохраняет имя и метаданные исходной функции, что важно для отладки и инструментов, которые используют рефлексию.

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

  • Фабрика декораторов нужна, когда декоратору требуются параметры.
  • Она позволяет не плодить похожие декораторы для разных сценариев.
  • Подходит для логирования, метрик, кеширования, проверки прав, троттлинга.
  • Упрощает архитектуру: сквозная логика отделяется от бизнес-кода.
  • @decorator(param) — это обычно вызов фабрики, а не самого декоратора.
  • functools.wraps желательно использовать почти всегда, чтобы не терять метаданные функции.