DEV Community

DevCorner2
DevCorner2

Posted on

๐ŸŽ Decorator Design Pattern โ€” LLD + Java + Real Use Cases

Add behavior to individual objects dynamically without altering their structure โ€” a flexible alternative to subclassing.


๐Ÿง  What is the Decorator Pattern?

The Decorator Pattern is a structural design pattern that allows you to:

  • Attach additional responsibilities to objects at runtime
  • Wrap objects with other objects that enhance behavior
  • Maintain the original objectโ€™s interface

๐Ÿ“ฆ Use Cases (Real-World)

Context Example
โ˜• Coffee Shop Add milk, sugar, etc. to base beverage dynamically
๐Ÿงพ Billing System Add discounts, taxes, coupons to final price
๐Ÿ“„ I/O Streams (Java) BufferedReader, DataInputStream, GZIPOutputStream
๐Ÿ›ก๏ธ Security Layering Add logging, auth, audit, throttling to requests
๐Ÿงช Testing Mocks Mock + Spy + Log enhancement

๐ŸŽฏ When to Use It?

โœ… Use when:

  • You need to add features to objects dynamically and transparently
  • You want to avoid subclass explosion
  • You want to compose behavior in a flexible way

๐Ÿšซ Avoid if:

  • Object configuration is overly complex
  • All variations are known at compile time (prefer inheritance)

๐Ÿงฑ Pattern Structure

Component Role
Component (interface) Declares the core operation
ConcreteComponent The base implementation
Decorator (abstract) Holds a reference to a Component + delegates
ConcreteDecorator Adds extra behavior before/after delegate calls

๐Ÿ“ UML Diagram

+------------------+
|   Component      | <<interface>>
+------------------+
| +operation()     |
+------------------+
        โ–ฒ
        |
+-------------------+
| ConcreteComponent |
+-------------------+
| +operation()      |
+-------------------+
        โ–ฒ
        |
+-------------------+
|    Decorator      | <<abstract>>
+-------------------+
| - component: Component
| +operation()      |
+-------------------+
        โ–ฒ
+--------------------------+
|  ConcreteDecoratorA      |
+--------------------------+
| +operation()             |
+--------------------------+
Enter fullscreen mode Exit fullscreen mode

โ˜• Coffee Shop Example in Java

โœ… Beverage.java

public interface Beverage {
    String getDescription();
    double getCost();
}
Enter fullscreen mode Exit fullscreen mode

โœ… Espresso.java (ConcreteComponent)

public class Espresso implements Beverage {
    @Override
    public String getDescription() {
        return "Espresso";
    }

    @Override
    public double getCost() {
        return 100.0;
    }
}
Enter fullscreen mode Exit fullscreen mode

โœ… BeverageDecorator.java (Abstract Decorator)

public abstract class BeverageDecorator implements Beverage {
    protected Beverage beverage;

    public BeverageDecorator(Beverage beverage) {
        this.beverage = beverage;
    }
}
Enter fullscreen mode Exit fullscreen mode

โœ… MilkDecorator.java (ConcreteDecorator)

public class MilkDecorator extends BeverageDecorator {
    public MilkDecorator(Beverage beverage) {
        super(beverage);
    }

    @Override
    public String getDescription() {
        return beverage.getDescription() + ", Milk";
    }

    @Override
    public double getCost() {
        return beverage.getCost() + 20.0;
    }
}
Enter fullscreen mode Exit fullscreen mode

โœ… SugarDecorator.java

public class SugarDecorator extends BeverageDecorator {
    public SugarDecorator(Beverage beverage) {
        super(beverage);
    }

    @Override
    public String getDescription() {
        return beverage.getDescription() + ", Sugar";
    }

    @Override
    public double getCost() {
        return beverage.getCost() + 10.0;
    }
}
Enter fullscreen mode Exit fullscreen mode

โœ… Client.java

public class DecoratorClient {
    public static void main(String[] args) {
        Beverage espresso = new Espresso();
        System.out.println("Order 1: " + espresso.getDescription() + " | โ‚น" + espresso.getCost());

        Beverage customCoffee = new MilkDecorator(new SugarDecorator(new Espresso()));
        System.out.println("Order 2: " + customCoffee.getDescription() + " | โ‚น" + customCoffee.getCost());
    }
}
Enter fullscreen mode Exit fullscreen mode

๐Ÿงช Output

Order 1: Espresso | โ‚น100.0
Order 2: Espresso, Sugar, Milk | โ‚น130.0
Enter fullscreen mode Exit fullscreen mode

โœจ Benefits

Advantage Explanation
โœ… Flexible composition Add features without changing existing classes
โœ… Open/Closed Principle Extend behavior via composition
โœ… Reuse & layering Chain decorators to build behavior stacks
โœ… No subclass explosion Avoid subclassing for each variation

โš ๏ธ Limitations

  • ๐ŸŽ›๏ธ Complex configuration if decorators are stacked dynamically
  • ๐Ÿงฉ Debugging stack layers may be harder than single-class hierarchies

๐Ÿงพ Summary

Feature Value
Type Structural
Primary Intent Add behavior at runtime
Key Concepts Used Composition, Delegation
Java Real Usage InputStream, Logger, UI themes, Spring AOP

Top comments (0)