The Decorator pattern is usually used to extend the functionality of an object by extending one of it's current methods.
To illustrate, please consider an object object
and a decorator decorator
. object
has one method called methodA()
. decorator
, because we're in the Decorator pattern, also has this method by inheritance (both object
and decorator
eventually inherit from the same super-class which has methodA()
. Let's call it AbstractObject
).
methodA()
in object
looks like this:
public void methodA(){
// do stuff
}
methodA()
in decorator
looks like this:
public void methodA(){
// do some extra stuff.
wrappedObject.methodA(); // and then delegate to the wrapped object.
}
It would be used like this:
AbstractObject object = new ConcreteObject();
object.methodA(); // does stuff
object = new ConcreteDecorator(object);
object.methodA(); // does stuff and some more stuff. the extended methodA().
The point of decorator
is to extend the functionality of object
, and it does this by extending one of object
's current methods. So far, classic Decorator.
Now, my question:
As I said Decorator usually extends an object's functionality by adding content to one of the object's current methods.
But what if I wanted to use Decorator to add public methods to an object?
Please consider the following scenario where decorator
has another method methodB()
:
AbstractObject object = new ConcreteObject();
object.methodA(); // does stuff
object = new ConcreteDecorator(object);
((ConcreteDecorator)object).methodB();
// methodB() belongs to ConcreteDecorator() but not to AbstractObject().
As you see if I wanted to do this, I would have to cast object
to ConcreteDecorator
.
This exposes the concrete type of object
and the fact that it's decorated, and as such somewhat defeats the intent of the Decorator pattern. Also, the code invoking methodB()
would have to know object
is decorated. Again, not very much in the spirit of Decorator.
In light of this I have two questions:
-
Is the Decorator pattern ever used this way? Is it ever used to add
public methods to an object, as opposed to only 'extending' it's
current methods? -
Are there situations where this would be a good idea or a wise use of
Decorator?
Best Answer
The decorator pattern is typically used to avoid an explosion of subclasses. A common example involves UI windows that you may want to have any combination of n attributes (scrollbar, titlebar, resizable, movable, etc.).
Supporting all combinations of all those
N
attributes for all UI windowsM
subclasses would involve makingN * M
subclasses.The decorator pattern prevents the explosion by wrapping around the base window class' existing public methods.
The decorator pattern ideally would only require
N + M
classes in this case.For the case you have described, you are adding new public methods; therefore, the decorator pattern probably is not ideal. I cannot think of any situations where it would be ideal to add new methods via a decorator.
A few alternatives to consider:
Subtyping
It is valid to use subtyping to add methods, provided you are keeping the SOLID principles in mind. Therefore, you might consider extending the concrete object to support methodB and then design the decorator around it.
Adapter Pattern
Another way to view the problem: by adding a public method, you are changing the object's interface. This can be done by using the adapter pattern. To keep the concrete decorator simple, you might consider creating a decorator and then building an adapter for that decorator.