The decorator design pattern is a structural design pattern that is used for extending the functionality of existing classes without much of a change in the codebase. You can also look at this design pattern as a wrapper around the existing functionality.

Let’s dive into the example which will make things much clearer. We have some simple shapes for this example, now there’s a business requirement for filling it with a colour.

Existing classes and interface

As a base, we have the Shape interface

public interface Shape {
    void draw();
}

We have a Rectangle and Circle which implement the shape interface.

public class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("I have drawn a circle");
    }
}
public class Rectangle implements Shape {
    @Override
    public void draw() {
        System.out.println("I have drawn a Rectangle");
    }
}

New additions to extend the functionality

As per the new requirements, we have to fill the shapes with a colour. Thus, we add an abstract class that will help extend the functionality.

public abstract class ColourFillerDecorator implements Shape {
    protected Shape shape;
    public ColourFillerDecorator(Shape shape) {
        this.shape = shape;
    }
    public void draw() {
        shape.draw();
    }
}

We now extend the ColourFillerDecorator to have a concrete class which has a function to fill any colour inside the shape.

public class ColourFiller extends ColourFillerDecorator {
    private String colour;
    public ColourFiller(Shape shape, String colour) {
        super(shape);
        this.colour = colour;
    }
    private void fill() {
        System.out.println("Filled with: " + colour);
    }
    @Override
    public void draw() {
        shape.draw();
        fill();
    }
}

We now demonstrate the Decorator Pattern with the code below. If you want to use the decorator, keep the value of decorate as true, otherwise, you can change it to false.

public class DecoratorDemo {
    public static void main(String[] args) {
        Shape circle = new Circle();
        Shape rectangle = new Rectangle();
        boolean decorate = true;
        if (decorate) {
            ColourFiller circleColourFiller = new ColourFiller(circle, "RED");
            ColourFiller rectangleColourFiller = new ColourFiller(rectangle, "BLUE");
            circleColourFiller.draw();
            rectangleColourFiller.draw();
        } else {
            circle.draw();
            rectangle.draw();
        }
    }
}

Output when decorate value is true:

I have drawn a circle
Filled with: RED
I have drawn a Rectangle
Filled with: BLUE

Output when decorate value is false:

I have drawn a circle
I have drawn a Rectangle

Github link

Comments to: The Decorator Design Pattern

Your email address will not be published. Required fields are marked *

Attach images - Only PNG, JPG, JPEG and GIF are supported.

Login

Welcome to Typer

Brief and amiable onboarding is the first thing a new user sees in the theme.
Join Typer