# Decorator

> Wrap an object to add behavior at runtime — stack multiple wrappers for combined effects — without modifying the original class or creating a subclass.

- **Category**: Software Design
- **Subcategory**: structural
- **Canonical URL**: https://designpattern.fyi/patterns/decorator/

---

## Description
**Intent**: Attach new responsibilities to an object dynamically at runtime instead of baking them into subclasses at compile time.

**Context**: You have a Coffee class and want to support Milk, Sugar, Whip, Syrup add-ons in any combination. Creating a subclass for every combination (MilkCoffee, SugarMilkCoffee, WhipSugarMilkCoffee...) is obviously insane. You need a composable approach.

**Solution**: Decorators implement the same interface as the wrapped object and hold a reference to it. Each Decorator's method calls the wrapped object's method and adds its own behavior before or after. Stack Decorators to combine effects: `new WhipDecorator(new MilkDecorator(new Coffee()))`.


## Use Cases
Use when you need to add behaviors to objects at runtime in combinations — I/O streams with buffering, compression, encryption; UI components with borders, scrollbars, shadows.



## Implementation Example

```javascript
class Coffee {
  getCost() { return 10; }
  getDescription() { return "Simple coffee"; }
}

// Decorator
class MilkDecorator {
  constructor(coffee) { this.coffee = coffee; }
  getCost() { return this.coffee.getCost() + 2; }
  getDescription() { return this.coffee.getDescription() + ", milk"; }
}

let myCoffee = new Coffee();
myCoffee = new MilkDecorator(myCoffee);
console.log(myCoffee.getCost()); // 12
console.log(myCoffee.getDescription()); // "Simple coffee, milk"

```



## Trade-offs


### Advantages

- Add and remove responsibilities at runtime without touching the original class.

- Combine behaviors by stacking decorators — far more flexible than inheritance.




### Considerations & Drawbacks

- Deeply stacked decorators are hard to debug — hard to tell which layer is misbehaving.

- Removing a specific decorator from the middle of a stack is awkward.







---
**Reference**: [Original Source](https://refactoring.guru/design-patterns/decorator)

