> ## Documentation Index
> Fetch the complete documentation index at: https://akshanshgusain.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Decorator Pattern

> Structural Patterns

## Definition

**“Decorator Pattern attaches additional responsibilities to an object dynamically. Decorators provide a flexible
alternative to subclassing for extending functionality”**

## Explanation

You have a base interface or class (e.g. `Beverage`) and concrete implementations (`Espresso`, `Tea`). Instead of subclassing
every possible combination (e.g. `EspressoWithMilk`), you create Decorator classes that wrap a `Beverage` and add behavior
(e.g. `MilkDecorator`). Multiple decorators can wrap an object at runtime to accumulate behaviors. Each decorator has the
same interface, so it’s transparent to clients.

## Code

Here, `ConcreteComponent` is wrapped by decorators. `ConcreteDecoratorA` and `ConcreteDecoratorB` extend the behavior of
`ConcreteComponent` without modifying its code. The client\_code function shows how a component and its decorated versions behave.

```python theme={null}
class Component:
    def operation(self) -> str:
        pass

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

class Decorator(Component):
    def __init__(self, component: Component) -> None:
        self._component = component

    @property
    def component(self) -> Component:
        return self._component

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

class ConcreteDecoratorA(Decorator):
    def operation(self) -> str:
        return f"ConcreteDecoratorA({self.component.operation()})"

class ConcreteDecoratorB(Decorator):
    def operation(self) -> str:
        return f"ConcreteDecoratorB({self.component.operation()})"

def client_code(component: Component) -> None:
    print(f"RESULT: {component.operation()}", end="")

def main():
    simple = ConcreteComponent()
    print("Client: I've got a simple component:")
    client_code(simple)
    print("\n")

    decorator1 = ConcreteDecoratorA(simple)
    decorator2 = ConcreteDecoratorB(decorator1)
    print("Client: Now I've got a decorated component:")
    client_code(decorator2)
    print()

if __name__ == "__main__":
    main()

```

## Analogy

Adding condiments to a coffee order or layers to an outfit. E.g., Christmas tree: you start with a plain tree and attach
ornaments (decorators) like lights, tinsel, star, each adding functionality (light, color). Or a Window with scrollbars:
you start with a base window and add horizontal or vertical scroll decorator to extend its behavior.

## Interview Insights

**Use Case**: When you want to add responsibilities to objects at runtime. UI component styling (e.g. Swing’s JScrollPane
wraps a component), I/O streams (e.g. Java’s BufferedInputStream decorating a FileInputStream), or adding features
(e.g. text formatting). Helps avoid “explosion” of subclasses.\
**Advantages**: Provides more flexibility than static inheritance. You can combine decorators in any order/quantity.
Adheres to Single Responsibility: each decorator focuses on one feature.\
**Disadvantages**: A large number of small decorator classes can complicate design. Hard to configure in code if many
decorators are needed. Wrapping layers can be confusing to debug (many levels).\
**Common questions**: “Difference between Decorator and Adapter/Proxy?”, “Why use Decorator instead of inheritance?”,
“Show example (e.g. coffee with toppings)”, “What is the effect on existing code if we want to add a new feature
(decorator vs subclass)?”.\\
