Decorator Pattern

Category : Design Patterns | Sub Category : Structural design patterns | By Prasad Bonam Last updated: 2023-07-09 14:29:57 Viewed : 77

Decorator Pattern:

The Decorator pattern is a structural design pattern that allows behaviour to be added to an object dynamically at runtime by wrapping it in an object of a decorator class. It provides an alternative to sub classing for extending functionality. The Decorator pattern allows you to add new behaviours to objects without modifying their original class. Here is an example of implementing the Decorator pattern in Java:

// Component interface interface Coffee { double getCost(); String getDescription(); } // Concrete component class SimpleCoffee implements Coffee { @Override public double getCost() { return 1.0; } @Override public String getDescription() { return "Simple Coffee"; } } // Decorator class abstract class CoffeeDecorator implements Coffee { protected Coffee decoratedCoffee; public CoffeeDecorator(Coffee coffee) { this.decoratedCoffee = coffee; } @Override public double getCost() { return decoratedCoffee.getCost(); } @Override public String getDescription() { return decoratedCoffee.getDescription(); } } // Concrete decorator class MilkDecorator extends CoffeeDecorator { public MilkDecorator(Coffee coffee) { super(coffee); } @Override public double getCost() { return super.getCost() + 0.5; } @Override public String getDescription() { return super.getDescription() + ", Milk"; } } // Concrete decorator class WhipDecorator extends CoffeeDecorator { public WhipDecorator(Coffee coffee) { super(coffee); } @Override public double getCost() { return super.getCost() + 0.7; } @Override public String getDescription() { return super.getDescription() + ", Whip"; } } // Client code public class Client { public static void main(String[] args) { Coffee coffee = new SimpleCoffee(); System.out.println("Cost: " + coffee.getCost() + ", Description: " + coffee.getDescription()); coffee = new MilkDecorator(coffee); System.out.println("Cost: " + coffee.getCost() + ", Description: " + coffee.getDescription()); coffee = new WhipDecorator(coffee); System.out.println("Cost: " + coffee.getCost() + ", Description: " + coffee.getDescription()); } }

In this example:

  • The Coffee interface defines the component interface, which provides the basic behaviour for a coffee object.
  • The SimpleCoffee class is a concrete component that implements the Coffee interface.
  • The CoffeeDecorator class is an abstract decorator class that implements the Coffee interface and maintains a reference to a Coffee object. It provides a default implementation of the interface methods by delegating the calls to the wrapped object.
  • The MilkDecorator and WhipDecorator classes are concrete decorators that extend the CoffeeDecorator class. They add specific behaviors to the decorated coffee object by overriding the interface methods and adding their own functionality.
  • The client code in the Client class demonstrates the usage of the decorators. It creates a SimpleCoffee object and wraps it with MilkDecorator and WhipDecorator objects. The cost and description of the coffee are printed after each decorator is applied.

By using the Decorator pattern, you can add new functionalities to an object dynamically by wrapping it with one or more decorators. This pattern allows for flexible extension of behavior without modifying the original object or its subclasses. It promotes code reusability, separation of concerns, and easy customization of objects at runtime.

Related Articles

Leave a Comment: