Decorator Design Pattern

Loading...
By technoayan
Design-PatternDecorator
Decorator Design Pattern
0 min read
LLD
Design-Pattern
Decorator

Decorator Design Pattern

Understand the Decorator Design Pattern in Java with simple examples. Learn how to add new behaviors to objects dynamically without altering their structure.

🧩 Decorator Design Pattern in Java

The Decorator Pattern is a structural design pattern that allows you to add new behavior to an object without modifying its code.


πŸ• Real-Life Analogy

Think of a pizza shop:

  • Base pizza = plain
  • You can add cheese, veggies, or paneer without modifying the original pizza.

This is what Decorator Pattern does: it wraps an object to add new behavior.


🎯 When to Use It?

  • When you want to add features to objects at runtime.
  • When using inheritance would lead to a large number of subclasses.
  • When you need to follow the Open/Closed Principle (Open for extension, Closed for modification).

πŸ”§ Example – Pizza Toppings

Let’s build a system where we can decorate a basic pizza with toppings.


πŸ”Έ Step 1: Create a Base Interface

β˜•JAVA
public interface Pizza {
    String getDescription();
    double getCost();
}

πŸ”Έ Step 2: Concrete Component

β˜•JAVA
public class Margherita implements Pizza {
    public String getDescription() {
        return "Margherita";
    }

    public double getCost() {
        return 100.0;
    }
}

πŸ”Έ Step 3: Abstract Decorator

β˜•JAVA
public abstract class ToppingDecorator implements Pizza {
    protected Pizza pizza;

    public ToppingDecorator(Pizza pizza) {
        this.pizza = pizza;
    }

    public String getDescription() {
        return pizza.getDescription();
    }

    public double getCost() {
        return pizza.getCost();
    }
}

πŸ”Έ Step 4: Concrete Decorators (Toppings)

β˜•JAVA
public class Cheese extends ToppingDecorator {
    public Cheese(Pizza pizza) {
        super(pizza);
    }

    public String getDescription() {
        return super.getDescription() + ", Cheese";
    }

    public double getCost() {
        return super.getCost() + 30.0;
    }
}

public class Olives extends ToppingDecorator {
    public Olives(Pizza pizza) {
        super(pizza);
    }

    public String getDescription() {
        return super.getDescription() + ", Olives";
    }

    public double getCost() {
        return super.getCost() + 20.0;
    }
}

πŸ”Έ Step 5: Test the Pizza Builder

β˜•JAVA
public class DecoratorDemo {
    public static void main(String[] args) {
        Pizza pizza = new Margherita();
        pizza = new Cheese(pizza);
        pizza = new Olives(pizza);

        System.out.println("Pizza: " + pizza.getDescription());
        System.out.println("Total Cost: β‚Ή" + pizza.getCost());
    }
}

βœ… Output

Pizza: Margherita, Cheese, Olives Total Cost: β‚Ή150.0

πŸ“Œ Key Concepts

| Concept | Description | | ----------------- | ------------------------------------------------------ | | Component | Base interface or class (e.g., Pizza) | | ConcreteComponent | Actual implementation (e.g., Margherita) | | Decorator | Wraps component to add behavior (e.g., Cheese, Olives) |


πŸ” Real-World Use Cases

  • βœ… Java I/O streams: BufferedInputStream, DataInputStream
  • βœ… Spring Security Filters
  • βœ… UI frameworks (adding scrollbars, borders to components)
  • βœ… Logging enhancements

🧠 Interview Q&A

Q: What type of pattern is Decorator? A: Structural

Q: What's the difference between Decorator and Inheritance? A:

  • Inheritance is compile-time and static
  • Decorator is runtime and flexible

Q: Can we use multiple decorators? A: Yes, decorators can be stacked/wrapped as many times as needed.


πŸ’‘ Decorator vs Strategy vs Adapter

| Pattern | Purpose | | --------- | -------------------------------- | | Decorator | Add responsibilities dynamically | | Strategy | Select algorithm at runtime | | Adapter | Convert one interface to another |


🧠 SOLID Principle in Play

  • O – Open/Closed Principle: Easily extend object behavior without modifying their code.

πŸ“š Summary

  • βœ… Decorator adds new behavior to objects without altering their structure.
  • 🧱 Follows composition over inheritance.
  • πŸ› οΈ Helps write flexible, reusable, and extensible code.
  • βš™οΈ Used in Java libraries like I/O and GUI toolkits.

Thanks for reading!

technoayan

Author & Tech Enthusiast

"Keep learning, keep growing, and keep sharing knowledge with the world."

Rate This Post

Share your thoughts and help others discover great content

Sign in to rate this post and share your feedback

Community Rating

No ratings yet. Be the first to rate this post!

Comments (0)

Leave a Comment

No comments yet. Be the first to share your thoughts!

TechnoBlogs

by Ayan Ahmad

Exploring the world of technology through insightful articles, tutorials, and personal experiences. Join me on this journey of continuous learning and innovation.

Stay Updated

Built With

React
Next.js
Tailwind
Firebase
Powered by Coffee

Every line of code written with love and caffeine β˜•

Β© 2025 TechnoBlogsβ€’Made withbyAyan Ahmad

Open source β€’ Privacy focused β€’ Built for developersβ€’Privacy Policyβ€’Terms of Service