StructuralPythonverifiedVerified

Decorator Pattern in Python

Attaches additional responsibilities to an object dynamically by wrapping it in decorator objects that share the same interface.

How to Implement the Decorator Pattern in Python

1Step 1: Define the component interface and base implementation

from typing import Protocol


class Component(Protocol):
    def operation(self) -> str: ...


class ConcreteComponent:
    def operation(self) -> str:
        return "ConcreteComponent"

2Step 2: Create the base decorator and concrete decorators

class BaseDecorator:
    def __init__(self, component: Component) -> None:
        self._wrappee = component

    def operation(self) -> str:
        return self._wrappee.operation()


class DecoratorA(BaseDecorator):
    def operation(self) -> str:
        return f"DecoratorA({super().operation()})"


class DecoratorB(BaseDecorator):
    def operation(self) -> str:
        return f"DecoratorB({super().operation()})"

3Step 3: Compose decorators and observe layered behavior

def client_code(component: Component) -> None:
    print("Result:", component.operation())


simple = ConcreteComponent()
client_code(simple)
# Result: ConcreteComponent

decorated = DecoratorB(DecoratorA(simple))
client_code(decorated)
# Result: DecoratorB(DecoratorA(ConcreteComponent))

Decorator Pattern Architecture

hourglass_empty

Rendering diagram...

lightbulb

Decorator Pattern in the Real World

Think of adding espresso shots and syrups to a coffee order. A plain coffee is the base component. Each addition—an espresso shot, vanilla syrup, oat milk—is a decorator that wraps the previous cup, adding its own cost and flavor. You can combine them in any order without the café needing a separate menu item for every combination.