Java Tutorial: Decorator Pattern 🎯

beginner
22 min

Java Tutorial: Decorator Pattern 🎯

Welcome to the Java Decorator Pattern tutorial! In this lesson, we'll explore a powerful design pattern that allows you to add new functionality to an object by placing it inside special wrapper objects, called decorators. Let's dive in!

What is the Decorator Pattern? 📝

A decorator is an object that wraps another object (known as the component) and provides additional responsibilities to it without altering its interface. In other words, decorators help you to dynamically change the behavior of an object at runtime.

Why Use the Decorator Pattern? 💡

  • Flexibility: Decorators offer a flexible way to extend the functionality of objects without creating a large number of concrete classes.
  • Open Design: The decorator pattern promotes an open design, making it easy to extend the functionality of a system without modifying existing code.
  • Reusability: Decorators can be reused across different components, making them a practical solution for adding new features.

The Decorator Pattern Components 📝

  1. Component: The base interface for objects that can be decorated.
  2. ConcreteComponent: The actual object that the decorators will wrap.
  3. Decorator: The wrapper object that provides additional functionality to the concrete component.

Creating a Simple Decorator Example 💡

Let's illustrate the decorator pattern with a practical example: a Coffee Shop!

java
// Component Interface public interface Beverage { double cost(); String description(); } // Concrete Component public class Espresso implements Beverage { public double cost() { return 1.99; } public String description() { return "Espresso"; } } // Decorator public abstract class BeverageDecorator implements Beverage { private Beverage beverage; public BeverageDecorator(Beverage beverage) { this.beverage = beverage; } public double cost() { return beverage.cost(); } public String description() { return beverage.description(); } } // Concrete Decorators public class Milk extends BeverageDecorator { public Milk(Beverage beverage) { super(beverage); } public double cost() { return super.cost() + 0.75; } public String description() { return super.description() + ", Milk"; } } public class Chocolate extends BeverageDecorator { public Chocolate(Beverage beverage) { super(beverage); } public double cost() { return super.cost() + 0.50; } public String description() { return super.description() + ", Chocolate"; } }

Now you can use the decorators to customize your beverages:

java
public class Main { public static void main(String[] args) { Beverage espresso = new Espresso(); Beverage milkEspresso = new Milk(espresso); Beverage chocolateMilkEspresso = new Chocolate(milkEspresso); System.out.println("Espresso: " + espresso.cost()); System.out.println("Espresso with Milk: " + milkEspresso.cost()); System.out.println("Espresso with Milk and Chocolate: " + chocolateMilkEspresso.cost()); } }

Output:

Espresso: 1.99 Espresso with Milk: 2.74 Espresso with Milk and Chocolate: 3.19
Quick Quiz
Question 1 of 1

What is the purpose of the decorator pattern in Java?

Key Takeaways 💡

  • Decorators add new behavior to objects without changing their interface.
  • Decorators offer flexibility, open design, and reusability.
  • A simple decorator example demonstrates the power of the decorator pattern.

Hope you enjoyed learning about the Decorator Pattern in Java! Stay tuned for more in-depth lessons on Java and various design patterns. Happy coding! 🚀