What is a Decorator Pattern?
The dictionary definition of the verb decorate is
make (something) look more attractive by adding extra items to it. Keeping in line with this definition, the decorator pattern allows you to enhance the functionality of an object without affecting other objects of the same class.
This is achieved via a combination of Abstract class and inheritance.
Advantages of Decorator Design Pattern
- It allows you to change functionality of a single object at runtime rather than the whole class.
- It embodies the single responsibility design principle, since one decorator class is responsible for a single thing.
Disdvantages of Decorator Design Pattern
- The application size can increase a lot as you will have many decorator classes.
- Component Interface – The base interface. This will be the interface whose concrete classes will be eventually decorated.
- Component Concrete Implementations – The concrete classes that implement the base interface.
- Decorator – An abstract class that will be the top hierarchical class for all the decorators that intend to be written for component interface.
- Concrete Decorators – The concrete classes that are actually adding functionality to the component concrete implementations.
In the above diagram, Shape is the Component Interface. The classes Rectangle and Circle are the concrete implementations of the shape interface. The shape decorator is an abstract class. The FillColor and BorderThickness classes are the concrete decorator classes that extend the ShapeDecorator class.
Let us take an example application where we have to draw a shape with some extensions like a thick border or a different color.
Let us define the Shape interface and the two concrete implementations of the shape interface. This is same as the interface in the Factory Pattern post.
Now let us define the shape decorator class. This class will extend the shape interface. It will also have a reference to an object of a concrete Shape class. It can have a default implementation of the draw function.
We will now define the two concrete implementations of the shape decorator, the FillColor class and the BorderThickness class. These classes will implement the draw function. It will extend the Concrete Shape’s draw function with whatever functionality it wants to add.
Bringing it all together.
You can find the complete code on github.
Decorator Pattern in Java Library
The java.io package includes several decorators.
You can see an example of BufferedInputStream class that acts as a decorator on the FileInputStream.