Category : Design Patterns | Sub Category : Structural design patterns | By Prasad Bonam Last updated: 2023-07-09 14:29:57 Viewed : 77
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:
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:
Coffee
interface defines the component interface, which provides the basic behaviour for a coffee object.SimpleCoffee
class is a concrete component that implements the Coffee
interface.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.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.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.