Decorator Pattern

Decorator pattern allows to add new functionality an existing object without altering its structure. Decorators provide a flexible alternative to subclassing for extending functionality. Subclassing adds behavior at compile time, and the change affects all
instances of the original class; decorating can provide new behavior at runtime for individual objects. The Decorator Design Pattern simplifies code because you add functionality using many simple classes. Also, rather than rewrite old code you can extend it
with new code and that is always good.

Lets take an example of a Coffee house offering many beverages.

Approach 1 – was to make a abstract Beverage class having description flied with getter and an abstract cost() method. Now the different kind of beverages will extend this class like Espresso, Decaf, HouseBlend etc and set the description and implement the cost() method. Now each coffee can have condiments like Whip, Mocha, Soy, Steamed Milk etc. In order to accomodate, they needed to create all possible classes like HouseBlendWithSoy, HouseBlendWithWhip, HouseBlendWithSoyWhip etc. This resulted in creating a huge number of classes, obiviously difficult to manage.

Approach 2 – Another way is to have boolean variables for Whip, Soy, Mocha and other possible condiments in the beverage class. This beverage class calucates the cost by these valuse in its cost() methos. Now subclasses like HouseBlend, Espresso extend this and set these boolean values and override cos()t method. In this overriden method they first call the super class cost() methos before adding to the cost. This way the classes created will be less. But this approach has its own flaws like – New addition of condiments will force Beverage class to change, new beverage like lice tea will still have whip etc when they actually dont need it.

Decorator way – If the custor wants HouseBlend with Mocha and Whip – Take a HouseBlend object, decorate it with Mocha object, decorate this with Whip object and then call the cost() method on the final object that will give the toatl cost. basic UML diagram of the decorator pattern is as follows:

Above, the ConcreteComponent will be our Espresso, HouseBlend, Decaf classes. ConcreteDecorator will be our Soy, Whip, Mocha classes. We’re subclassing the abstract class Beverage in order to have the correct type, not to inherit its behavior. The behavior comes in through the composition of decorators with the base components as well as other decorators.We can implement new decorators at any time to add new behavior. If we relied on inheritance, we’d have to go in and change existing code any time we wanted new behavior.

As you can see, with each addition/decorating the object the cost increases.

Note – We can use interface instead of abstract class also. Decorators are typically created by using other patterns like Factory and
Builder. Once we’ve covered these patterns, you’ll see that the creation of the concrete component with its decorator is “well encapsulated”.

When to use Decorator pattern in Java

When sub classing is become impractical and we need large number of different possibilities to make independent object or we can say we have number of combination for an object.

Secondly when we want to add functionality to individual object not to all object at run-time we use decorator design pattern.