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)