Design Patterns – Can the Decorator Pattern Be Used Without an Interface?

decoratordesign-patternsinterfaces

Most of the resources I've seen about the Decorator pattern look like the following:

interface Tea
{
    public double cost();
}
class BasicTea implements Tea
{
    public double cost() { return 1.99; }
}
abstract class TeaDecorator implements Tea
{
    private Tea base;
    public TeaDecorator(Tea tea) { this.base = tea; }
    public double cost() { return this.base.cost(); }
}
class TeaWithMilk extends TeaDecorator
{
    public TeaWithMilk(Tea tea) { this.base = tea; }
    public double cost() { return this.base.cost() + 0.30; }
}
class TeaWithSugar extends TeaDecorator
{
    public TeaWithSugar(Tea tea) { this.base = tea; }
    public double cost() { return this.base.cost() + 0.10; }
}

decoratedTea = new TeaWithSugar(new TeaWithMilk(new BasicTea()));

However, I noticed the following approach also works – decoratedTea.cost() returns the same value as above.

class Tea
{
    public double cost() { return 1.99; }
}
abstract class TeaDecorator extends Tea
{
    private Tea base;
    public TeaDecorator(Tea tea) { this.base = tea; }
    public double cost() { return this.base.cost(); }
}
class TeaWithMilk extends TeaDecorator
{
    public TeaWithMilk(Tea tea) { this.base = tea; }
    public double cost() { return this.base.cost() + 0.30; }
}
class TeaWithSugar extends TeaDecorator
{
    public TeaWithSugar(Tea tea) { this.base = tea; }
    public double cost() { return this.base.cost() + 0.10; }
}

decoratedTea = new TeaWithSugar(new TeaWithMilk(new Tea()));

Is there any problem with this method? If I would not otherwise have an interface for Tea, is it necessary to add one just to implement the Decorator pattern?

Best Answer

You can certainly implement the Decorator pattern without the language keyword interface, because you can write decorators in languages that don't distinguish at the keyword level between a class with no implemented methods, one with some un-implemented methods and one with only implemented methods. (Java and C#'s interface, abstract class and class). C++ uses class for all three.

What you can't do is talk about the Decorator pattern without the concept of the Interface of a class, because the essence of Decorator is providing something of the same Interface and an implementation that delegates (some portion) to an existing implementation of that Interface