WalzoneInterview Prep
📞 Interviewing soon? Practice with a realistic AI mock phone interview — it calls you, then scores you. First 15 min FREE →

Design Patterns · Expert · question 64 of 100

How would you handle the Decorator pattern with multiple decorators that need to be applied in a specific order, and how would you handle potential conflicts?

📕 Buy this interview preparation book: 100 Design Patterns questions & answers — PDF + EPUB for $5

The Decorator pattern provides a flexible alternative to inheritance for extending the functionality of a class at runtime. However, when we have multiple decorators in use, we may need to apply them in a specific order to achieve the desired behavior.

To handle multiple decorators in a specific order, we can chain them together in a particular sequence. Each decorator wraps the component it decorates, and the wrapped component is passed along the chain until it reaches the final decorator in the sequence. In this way, each decorator adds its own behavior to the component and passes the modified component to the next decorator in the chain until the final behavior is achieved.

To illustrate this, let’s consider an example of a coffee shop application that allows customers to order different types of coffee with extra toppings. We can have multiple decorators that add different toppings, such as milk, sugar, whipped cream, and cinnamon.

We can start by defining an interface representing the basic coffee component:

public interface Coffee {
    double getCost();
    String getDescription();
}

Next, we can create a concrete implementation of the coffee component:

public class SimpleCoffee implements Coffee {
    @Override
    public double getCost() {
        return 1.0;
    }

    @Override
    public String getDescription() {
        return "Simple coffee";
    }
}

Now, we can define the decorator interface, which extends the Coffee interface and adds the functionality of adding extra toppings:

public interface CoffeeDecorator extends Coffee {
}

We can implement the decorator interface for each topping we want to add, such as milk, sugar, whipped cream, and cinnamon. Each decorator adds the cost and description of its topping to the wrapped coffee component:

public class MilkDecorator implements CoffeeDecorator {
    private Coffee coffee;

    public MilkDecorator(Coffee coffee) {
        this.coffee = coffee;
    }

    @Override
    public double getCost() {
        return coffee.getCost() + 0.5;
    }

    @Override
    public String getDescription() {
        return coffee.getDescription() + ", milk";
    }
}

public class SugarDecorator implements CoffeeDecorator {
    private Coffee coffee;

    public SugarDecorator(Coffee coffee) {
        this.coffee = coffee;
    }

    @Override
    public double getCost() {
        return coffee.getCost() + 0.2;
    }

    @Override
    public String getDescription() {
        return coffee.getDescription() + ", sugar";
    }
}

// Similar decorators for whipped cream and cinnamon

Finally, we can use the decorators in a specific order to create a custom coffee with the desired toppings:

Coffee customCoffee = new SugarDecorator(new WhippedCreamDecorator(
                        new MilkDecorator(new SimpleCoffee())));
System.out.println(customCoffee.getDescription() + " costs $" + customCoffee.getCost());

In this example, we apply the decorators in the order of Milk, WhippedCream, Sugar, and SimpleCoffee. The output of the code will be:

Simple coffee, milk, whipped cream, sugar costs $2.2

In case of potential conflicts, we need to carefully design our decorators to avoid overriding each other’s functionality. For example, we can have a decorator that adds more coffee instead of water, and this decorator should be applied before any decorator that adds milk, to avoid diluting the coffee flavor. In general, we should follow the Single Responsibility Principle and design our decorators to add independent and cohesive features to the component they decorate.

Reading is step one. Saying it out loud is the interview. Our AI interviewer calls your phone and runs a realistic Design Patterns interview — then scores it.
📞 Practice Design Patterns — free 15 min
📕 Buy this interview preparation book: 100 Design Patterns questions & answers — PDF + EPUB for $5

All 100 Design Patterns questions · All topics