interface Dress {
public void assemble();
}
class BasicDress implements Dress {
@Override public void assemble() {
System.out.println("Basic Dress Features");
}
}
class DressDecorator implements Dress {
protected Dress dress;
public DressDecorator(Dress c) {
this.dress = c;
}
@Override public void assemble() {
this.dress.assemble();
}
}
class SportyDress extends DressDecorator {
public SportyDress(Dress c) {
super(c);
}
@Override public void assemble() {
super.assemble();
System.out.println("Adding Sporty Dress Features");
}
}
class FancyDress extends DressDecorator {
public FancyDress(Dress c) {
super(c);
}
@Override
public void assemble() {
super.assemble();
System.out.println("Adding Fancy Dress Features");
}
}
public class DecoratorPatternTest {
public static void main(String[] args) {
Dress sportyDress = new SportyDress(new BasicDress());
sportyDress.assemble();
System.out.println();
Dress fancyDress = new FancyDress(new BasicDress());
fancyDress.assemble();
System.out.println();
}
}
Why do we need an interface in the decorator design pattern?
CodePudding user response:
Unless you have in mind some more complex logic that justifies that class structure, I think you have there 1 level of redundancy at a conceptual level. DressDecorator is a generic that is subclassed by FancyDress and SportyDress. That's fine. Then you might need an interface to implement some logic that needs to be common to other classes as well. But calling it Dress may be too specific, something like Wear could be more general. And it could be implemented by other wearables. In this case, I don't see what you would need that BasicWhatever for.
CodePudding user response:
The main reason for using an interface in the decorator pattern is that it is more flexible than using a class hierarchy.
Your code wants to use Dress
instances without caring whether it is working with a BasicDress
, a SportyDress
or some other decorated Dress
instance.
In Java you have two possibilities to implement such a design:
- make
Dress
a (possibly abstract) class and extend it inBasicDress
andDressDecorator
- make
Dress
an interface and implement it inBasicDress
andDressDecorator
Of these two options the option to make Dress
an interface is more flexible because this means that DressDecorator
could extend some other, unrelated class.