The Decorator Design Pattern in Object-Oriented Programming
The Decorator design pattern is a structural pattern used in object-oriented programming to add new functionality to an existing object dynamically. It provides an alternative to inheritance and composition and is often used in situations where multiple instances of the same class would require unique combinations of behaviors.
In the Decorator pattern, a class is wrapped in another class with the added functionality. This wrapped class is referred to as the decorator and the original class is referred to as the component. The decorator implements the same interface as the component, so it can be used interchangeably with the original class.
One of the main benefits of the Decorator pattern is that it allows for easy modification of an object’s behavior at runtime. Instead of having to create multiple subclasses to add new behaviors, you can simply wrap the original object in a decorator class with the added functionality.
Here’s an example of how the Decorator pattern could be used in a simple Java program:
interface Shape {
void draw();
}
class Circle implements Shape {
public void draw() {
System.out.println("Drawing Circle");
}
}
abstract class ShapeDecorator implements Shape {
protected Shape decoratedShape;
public ShapeDecorator(Shape decoratedShape) {
this.decoratedShape = decoratedShape;
}
public void draw() {
decoratedShape.draw();
}
}
class RedShapeDecorator extends ShapeDecorator {
public RedShapeDecorator(Shape decoratedShape) {
super(decoratedShape);
}
@Override
public void draw() {
decoratedShape.draw();
setRedBorder(decoratedShape);
}
private void setRedBorder(Shape decoratedShape) {
System.out.println("Border Color: Red");
}
}
public class DecoratorPatternDemo {
public static void main(String[] args) {
Shape circle = new Circle();
Shape redCircle = new RedShapeDecorator(new Circle());
Shape redRectangle = new RedShapeDecorator(new Rectangle());
System.out.println("Circle with normal border");
circle.draw();
System.out.println("\nCircle of red border");
redCircle.draw();
System.out.println("\nRectangle of red border");
redRectangle.draw();
}
}
In this example, the Circle
class implements the Shape
interface and the RedShapeDecorator
class is used to add a red border to the shape. The RedShapeDecorator
class extends the ShapeDecorator
abstract class, which implements the Shape
interface and contains a reference to the original Shape
object.
The RedShapeDecorator
class overrides the draw
method to add the red border to the shape after it has been drawn. The setRedBorder
method is used to set the red border for the shape.
In conclusion, the Decorator pattern provides a flexible alternative to inheritance and composition. It allows for easy modification of an object’s behavior at runtime and can be used in a variety of programming scenarios to add new functionality to an existing object.