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.
Disadvantages of Decorator Design Pattern
The application size can increase a lot as you will have many decorator classes.
Terminologies
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.
UML diagram
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.
Java Implementation
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
You can see an example of BufferedInputStream class that acts as a decorator on the FileInputStream.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 thoughts on “Decorator Design Pattern – Implementation in Java”