# How to Implement the Decorator Pattern for Dynamic Feature Addition in Java

> Dynamically add features to Java objects at runtime using the Decorator pattern. Learn how to extend behavior without modifying original code and avoid subclass explosions.

- Repository: [Ilkka Seppälä/java-design-patterns](https://github.com/iluwatar/java-design-patterns)
- Tags: how-to-guide
- Published: 2026-02-27

---

**The Decorator pattern lets you extend object behavior at runtime by wrapping components in decorator classes that implement the same interface, enabling dynamic feature addition without modifying original source code or creating subclass explosions.**

The Decorator pattern is a structural design pattern that solves the problem of extending object functionality without inheritance. In the `iluwatar/java-design-patterns` repository, this pattern is demonstrated through a practical "troll" example that shows how to implement Decorator pattern for dynamic feature addition in Java by wrapping objects to augment their capabilities at runtime.

## What Is the Decorator Pattern?

The Decorator pattern attaches additional responsibilities to an object dynamically. It provides a flexible alternative to subclassing for extending functionality. Instead of creating multiple subclasses to combine various features, you create decorator classes that wrap the original component and add new behavior before or after delegating to the wrapped object.

This approach follows the **Single Responsibility Principle** by separating concerns into distinct classes and the **Open/Closed Principle** by allowing extension without modification.

## Project Structure and Key Components

The implementation in `iluwatar/java-design-patterns` follows the classic Decorator structure with four main elements located in `decorator/src/main/java/com/iluwatar/decorator/`.

### Component Interface

The `Troll` interface defines the contract that both concrete components and decorators must implement. Located in [`Troll.java`](https://github.com/iluwatar/java-design-patterns/blob/main/Troll.java), it declares three core operations:

```java
public interface Troll {
    void attack();
    int getAttackPower();
    void fleeBattle();
}

```

### Concrete Component

`SimpleTroll` in [`SimpleTroll.java`](https://github.com/iluwatar/java-design-patterns/blob/main/SimpleTroll.java) provides the base implementation of the `Troll` interface. This represents the object to which additional features will be added dynamically:

```java
@Slf4j
public class SimpleTroll implements Troll {
    @Override
    public void attack() {
        LOGGER.info("The troll tries to grab you!");
    }

    @Override
    public int getAttackPower() {
        return 10;
    }

    @Override
    public void fleeBattle() {
        LOGGER.info("The troll shrieks in horror and runs away!");
    }
}

```

### Concrete Decorator

`ClubbedTroll` in [`ClubbedTroll.java`](https://github.com/iluwatar/java-design-patterns/blob/main/ClubbedTroll.java) demonstrates how to implement dynamic feature addition. It wraps a `Troll` instance and augments its behavior:

```java
@Slf4j
@RequiredArgsConstructor
public class ClubbedTroll implements Troll {
    private final Troll decorated;

    @Override
    public void attack() {
        decorated.attack();
        LOGGER.info("The troll swings at you with a club!");
    }

    @Override
    public int getAttackPower() {
        return decorated.getAttackPower() + 10;
    }

    @Override
    public void fleeBattle() {
        decorated.fleeBattle();
    }
}

```

## Implementing the Decorator Pattern Step by Step

To implement the Decorator pattern for dynamic feature addition in your own Java projects, follow this systematic approach demonstrated in the `iluwatar/java-design-patterns` repository.

### Step 1: Define the Component Interface

Create an interface that declares the operations shared by concrete components and decorators. This ensures type compatibility and allows transparent wrapping.

### Step 2: Create the Concrete Component

Implement the interface with your base class. This object represents the starting point to which you will add features dynamically.

### Step 3: Build the Concrete Decorator

Create a decorator class that:
- Implements the same interface as the component
- Stores a reference to the wrapped object (typically via constructor injection)
- Delegates calls to the wrapped object before or after adding new behavior

### Step 4: Compose Objects at Runtime

In your client code, instantiate the concrete component, then wrap it with decorators as needed. The [`App.java`](https://github.com/iluwatar/java-design-patterns/blob/main/App.java) file in the repository demonstrates this composition:

```java
public class App {
    public static void main(String[] args) {
        // Simple troll
        Troll simpleTroll = new SimpleTroll();
        simpleTroll.attack();
        System.out.println(simpleTroll.getAttackPower());
        
        // Decorated troll with club
        Troll clubbedTroll = new ClubbedTroll(simpleTroll);
        clubbedTroll.attack();
        System.out.println(clubbedTroll.getAttackPower());
    }
}

```

## How Runtime Decoration Works

The magic of dynamic feature addition happens through **composition and delegation**. When `ClubbedTroll.attack()` executes, it first calls `decorated.attack()` to preserve the original behavior, then adds the club swing. This chaining allows you to stack multiple decorators:

```java
Troll superTroll = new ClubbedTroll(new SimpleTroll());
// Could add: new ArmoredTroll(new ClubbedTroll(new SimpleTroll()));

```

Because both decorators and components implement `Troll`, the client code in [`App.java`](https://github.com/iluwatar/java-design-patterns/blob/main/App.java) treats decorated objects identically to simple ones. This **transparent wrapping** enables you to add responsibilities dynamically without affecting existing code or creating complex inheritance trees.

## Summary

- The Decorator pattern enables **runtime behavior extension** by wrapping objects in decorator classes that share the same interface as the components they decorate.
- In `iluwatar/java-design-patterns`, the implementation uses `Troll` as the component interface, `SimpleTroll` as the concrete component, and `ClubbedTroll` as the concrete decorator located in `decorator/src/main/java/com/iluwatar/decorator/`.
- Decorators maintain a reference to the wrapped object and use **delegation** to preserve original behavior while adding new features.
- This approach follows the Open/Closed Principle, allowing you to add functionality without modifying existing source code or creating subclass explosions.

## Frequently Asked Questions

### What is the difference between the Decorator pattern and inheritance?

Inheritance extends behavior statically at compile time by creating new subclasses, which leads to rigid class hierarchies and the "class explosion" problem when combining multiple features. The Decorator pattern extends behavior dynamically at runtime through composition, allowing you to add and combine responsibilities by wrapping objects without creating new subclasses.

### Can you stack multiple decorators on the same object?

Yes, you can stack decorators because both decorators and concrete components implement the same interface. You can wrap a `SimpleTroll` with a `ClubbedTroll`, then wrap that result with another decorator like `ArmoredTroll`, creating a chain of added behaviors while maintaining type compatibility with the original `Troll` interface.

### When should you use the Decorator pattern versus the Strategy pattern?

Use the Decorator pattern when you need to add responsibilities to objects dynamically and transparently, and when extension by subclassing would produce too many classes to maintain. Use the Strategy pattern when you need to vary the entire algorithm or behavior of a class, rather than layering additional responsibilities around an existing object.

### Does the Decorator pattern modify the original object?

No, the Decorator pattern does not modify the original object's code or internal state. It creates a new wrapper object that holds a reference to the original component and delegates calls to it. The original `SimpleTroll` object remains unchanged and unaware that it is being decorated, preserving the integrity of existing code while enabling new functionality.