0
0
LldConceptBeginner · 3 min read

Decorator Pattern: Definition, Example, and Use Cases

The decorator pattern is a design pattern that lets you add new features to an object dynamically without changing its structure. It wraps the original object with a new object that adds the extra behavior, keeping the original object intact.
⚙️

How It Works

Imagine you have a plain coffee, but you want to add milk or sugar without changing the coffee itself. The decorator pattern works like adding layers of toppings on your coffee cup. Each topping (decorator) adds something new, but the coffee (original object) stays the same.

Technically, the decorator pattern wraps an object inside another object that has the same interface. This wrapper object adds new behavior before or after delegating calls to the original object. You can stack many decorators to combine features flexibly.

💻

Example

This example shows a simple text message that can be decorated with uppercase and exclamation mark decorators.

python
from abc import ABC, abstractmethod

class Message(ABC):
    @abstractmethod
    def get_text(self) -> str:
        pass

class SimpleMessage(Message):
    def __init__(self, text: str):
        self._text = text

    def get_text(self) -> str:
        return self._text

class MessageDecorator(Message):
    def __init__(self, message: Message):
        self._message = message

    def get_text(self) -> str:
        return self._message.get_text()

class UppercaseDecorator(MessageDecorator):
    def get_text(self) -> str:
        return self._message.get_text().upper()

class ExclamationDecorator(MessageDecorator):
    def get_text(self) -> str:
        return self._message.get_text() + "!"

# Usage
simple = SimpleMessage("hello world")
upper = UppercaseDecorator(simple)
excited = ExclamationDecorator(upper)
print(excited.get_text())
Output
HELLO WORLD!
🎯

When to Use

Use the decorator pattern when you want to add responsibilities to objects at runtime without altering their code. It is helpful when subclassing would create too many classes or when you want to combine features flexibly.

Real-world examples include adding scrollbars or borders to UI elements, adding encryption or compression to data streams, or extending logging behavior dynamically.

Key Points

  • Decorator wraps an object to add new behavior.
  • It keeps the original object's interface unchanged.
  • Multiple decorators can be combined flexibly.
  • It avoids subclass explosion by using composition.

Key Takeaways

Decorator pattern adds features to objects dynamically without changing their code.
It works by wrapping the original object with a new object that has the same interface.
Use it to extend behavior flexibly and avoid many subclasses.
Decorators can be stacked to combine multiple behaviors.
It is widely used in UI, data streams, and logging enhancements.