Lifting this example from Wikipedia:
// the Window interface
interface Window {
public void draw(); // draws the Window
public String getDescription(); // returns a description of the Window
}
// implementation of a simple Window without any scrollbars
class SimpleWindow implements Window {
public void draw() {
// draw window
}
public String getDescription() {
return "simple window";
}
}
// abstract decorator class - note that it implements Window
abstract class WindowDecorator implements Window {
protected Window decoratedWindow; // the Window being decorated
public WindowDecorator (Window decoratedWindow) {
this.decoratedWindow = decoratedWindow;
}
public void draw() {
decoratedWindow.draw();
}
}
How would I, for example, allow a user to implement a decorator that decorates draw but not getDescription? In my actual code, there are 5 possible methods they could decorate.
The way I see it, I have 3 options:
- Put all 5 methods on the interface. The downside is this would force them to implement to 4 methods that would simply be calling the parent.
- Create 5 interfaces, one for each method. A bit clumsy.
- Don’t use an interface at all. Lose the design contract.
Are there any other options? If not, which of the above would be the best choice?
I’m using PHP.
You can make use of PHP’s constructor inheritance and create an abstract, default decorator implementation
AbstractWindowDecorator, which just gets the decorated Window and forward all calls to it. And now, when implementing new decorators, just inherit fromAbstractWindowDecoratorand override only these methods you need.AbstractWindowDecoratorstill implementsWindow, so you have your contract right and you don’t need to implement all methods. And moreover, all decorators created “old way”, without abstract class, will fit into this pattern, too.Decorator’s instantiation is just like it was in your example:
(In fact, you can do it even without constructor inheritance, but you’ll need to explicitly create an constructor for each decorator.)