Что такое паттерн Декоратор и к какому типу он относится

Ответ

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

Основная идея — расширение поведения объекта без создания подклассов. Это соответствует принципу открытости/закрытости (Open/Closed Principle).

Ключевые преимущества:

  • Гибкость: Новые обязанности можно добавлять и удалять во время выполнения программы.
  • Избегание наследования: Позволяет избежать разрастания иерархии классов.

Пример на Python:

# Базовый компонент
class TextComponent:
    def render(self) -> str:
        return "Hello, World!"

# Базовый декоратор
class BaseDecorator(TextComponent):
    def __init__(self, component: TextComponent):
        self._component = component

    def render(self) -> str:
        return self._component.render()

# Конкретные декораторы
class BoldDecorator(BaseDecorator):
    def render(self) -> str:
        return f"<b>{super().render()}</b>"

class ItalicDecorator(BaseDecorator):
    def render(self) -> str:
        return f"<i>{super().render()}</i>"

# Использование
plain_text = TextComponent()
print(f"Обычный текст: {plain_text.render()}")

bold_text = BoldDecorator(plain_text)
print(f"Жирный текст: {bold_text.render()}")

italic_bold_text = ItalicDecorator(bold_text)
print(f"Жирный и курсивный текст: {italic_bold_text.render()}")

# Вывод:
# Обычный текст: Hello, World!
# Жирный текст: <b>Hello, World!</b>
# Жирный и курсивный текст: <i><b>Hello, World!</b></i>

В этом примере BoldDecorator и ItalicDecorator добавляют HTML-теги к исходному тексту, не изменяя класс TextComponent.

Ответ 18+ 🔞

А, декоратор, ёпта! Ну это ж как в жизни, блядь: вот у тебя есть просто текст, голый, как сосиска без хлеба. А потом ты ему натягиваешь сверху жирный шрифт — это типа шапку надел. А потом ещё курсив сверху — это шарфик, блядь. И в итоге получается закутанный, как капуста, объект, но внутри-то он всё тот же, сука, текст!

Смотри, как это работает, в рот меня чих-пых. Есть у тебя базовый класс, ну, голый компонент. Он умеет только одно — render() возвращает «Hello, World!». Скукота, да? Ни тебе жирности, ни наклона, нихуя.

А потом приходят эти декораторы — такие обёртки, блядь, как подарочная бумага. Каждая обёртка говорит: «Я тоже компонент, ёпта, но я ещё и то, что внутри, оберну». То есть ты берёшь голый текст, суёшь его в BoldDecorator — и он уже в тегах <b>. А потом этот уже жирный текст ты можешь, блядь, запихнуть в ItalicDecorator — и он сверху ещё и в <i> завернётся. Получается матрёшка, сука! Одна внутри другой.

И главная фишка, блядь, в чём? Ты не лезешь в исходный класс TextComponent с паяльником и не плодишь кучу наследников вроде BoldText, ItalicText, BoldItalicText — а то там, глядишь, ещё и подчёркнутый понадобится, и зачёркнутый, блядь! Это же пиздец, иерархия классов вырастет, как грибы после дождя, а потом в ней сам запутаешься.

А тут — взял, обернул, что надо. Надо жирный? Обернул. Перехотел? Снял обёртку, и всё, блядь. Гибкость — овердохуища! Соответствует принципу «открыт для расширения, закрыт для изменений». То есть ты расширяешь функциональность, не ковыряясь в старом коде. Красота, да и только!

Вот смотри на пример кода — его не трогаем, он святой, блядь. Там всё наглядно: создали plain_text, потом bold_text — это тот же текст, но в жирной обёртке. А italic_bold_text — это уже две обёртки: сначала жирная, потом курсивная. И рендерит он их по порядку, изнутри наружу: сначала внутренний bold отработает, потом внешний italic его обернёт. В итоге <i><b>Hello, World!</b></i>. Логично же, ёпта?

Вот так и живём: не наследуемся, а оборачиваемся, как капустные голубцы. И всем хорошо, и код не превращается в монстра с тремя головами. Декоратор, блядь, он как приправа к борщу — добавил, стало вкуснее, а основа-то та же!