DEV Community

Fatima Alam
Fatima Alam

Posted on

Decorator Pattern

Who doesn't like customizations!!. Personally I wouldn't mind extra cheese on my pizza ๐Ÿ˜‰.

Just like that when you design systems made for customizations or those who let the user customize their orders you need the Decorator Design Pattern.

Imagine youโ€™re building a vehicle configuration platform (like Teslaโ€™s online configurator ๐Ÿš˜).

A customer can start with a basic car, and then add features dynamically like:

  1. Sunroof ๐ŸŒž
  2. Sports Package ๐ŸŽ๏ธ
  3. Advanced Sound System ๐Ÿ”Š Each feature adds extra cost and description, without changing the original Car class โ€” perfect use case for the Decorator Pattern.

Component Interface

interface Vehicle {
    String getDescription();
    double getCost();
}
Enter fullscreen mode Exit fullscreen mode

Concrete Component

class BasicCar implements Vehicle {
    @Override
    public String getDescription() {
        return "Basic Car";
    }

    @Override
    public double getCost() {
        return 500000.0; // base price
    }
}
Enter fullscreen mode Exit fullscreen mode

Abstract Decorator

abstract class VehicleDecorator implements Vehicle {
    protected Vehicle vehicle;

    public VehicleDecorator(Vehicle vehicle) {
        this.vehicle = vehicle;
    }

    @Override
    public String getDescription() {
        return vehicle.getDescription();
    }

    @Override
    public double getCost() {
        return vehicle.getCost();
    }
}
Enter fullscreen mode Exit fullscreen mode

Concrete Decorators

Each decorator adds a unique feature and modifies cost/description.

class SunroofDecorator extends VehicleDecorator {
    public SunroofDecorator(Vehicle vehicle) {
        super(vehicle);
    }

    @Override
    public String getDescription() {
        return vehicle.getDescription() + ", Sunroof";
    }

    @Override
    public double getCost() {
        return vehicle.getCost() + 40000.0;
    }
}

class SportsPackageDecorator extends VehicleDecorator {
    public SportsPackageDecorator(Vehicle vehicle) {
        super(vehicle);
    }

    @Override
    public String getDescription() {
        return vehicle.getDescription() + ", Sports Package";
    }

    @Override
    public double getCost() {
        return vehicle.getCost() + 120000.0;
    }
}

class SoundSystemDecorator extends VehicleDecorator {
    public SoundSystemDecorator(Vehicle vehicle) {
        super(vehicle);
    }

    @Override
    public String getDescription() {
        return vehicle.getDescription() + ", Premium Sound System";
    }

    @Override
    public double getCost() {
        return vehicle.getCost() + 35000.0;
    }
}
Enter fullscreen mode Exit fullscreen mode

Main Class โ€” Building the Custom Car

public class VehicleDecoratorDemo {
    public static void main(String[] args) {
        Vehicle car = new BasicCar();
        System.out.println(car.getDescription() + " โ‚น" + car.getCost());

        // Add sunroof
        car = new SunroofDecorator(car);
        System.out.println(car.getDescription() + " โ‚น" + car.getCost());

        // Add sports package
        car = new SportsPackageDecorator(car);
        System.out.println(car.getDescription() + " โ‚น" + car.getCost());

        // Add sound system
        car = new SoundSystemDecorator(car);
        System.out.println(car.getDescription() + " โ‚น" + car.getCost());
    }
}
Enter fullscreen mode Exit fullscreen mode

๐Ÿงฉ Real-World Analogies

Domain Example Decorators
E-Commerce Apply coupon, add gift wrap, add insurance
Vehicles Add GPS, airbags, turbo engine
Gaming Add armor, magic boost, invisibility cloak
Media Streaming Add subtitles, change resolution, enable HDR

Top comments (0)