Reputation: 798
Using the coffee decorator example shown on Wikipedia ( http://en.wikipedia.org/wiki/Decorator_pattern) how would it be possible for someone to be able to have methods that only the decorators have, for example, the milk decorator could have a method called "fatContent". Is this even possible with this type of design pattern? If not, what kind of pattern could I use to accomplish this?
Upvotes: 6
Views: 1709
Reputation: 160191
You could, but you'd need to know the type in order to actually call the method (assuming no reflection etc.) if it doesn't match the type you're passing around.
Types determine what's known at compile time: if CoffeeDecorater
doesn't include a fatContent
signature, nothing receiving a CoffeeDecoractor
knows the method exists.
You could create an additional interface, but you'd need to either know that it existed so you could check for it (instanceof
), or interrogate the class to check for a specific signature (reflection).
Java either knows a method exists at compile time, or checks for it at runtime.
Upvotes: 9
Reputation: 115328
Decorator pattern by definition does not allow adding methods other than those that are defined in the interface. Actually you can always add methods to any class but once these methods are not defined in the implementing interface client cannot call them using this interface.
Simple solution to your problem is to define several interfaces, e.g. Coffee and Milk. Then you can define class Capuchino
that implements both interfaces and probably holds 2 instances: SimpleCofee
and FoamedMilk
. But this solution looks more as a combination of Decorator and Facade.
Upvotes: 3
Reputation: 88707
The decorators can have any number of specific methods. You might introduce a decorator specific interface that decorators implement in addition to implementing the decorated interface.
However, someone has to know those methods exist, thus either the decorator has to call the method internally, the caller has to know it uses a decorator instead of the decorated object (you could test using instanceof
) or use reflection to check for those methods.
Upvotes: 4