Java Structural Design Patterns – Decorator Pattern
The Decorator Pattern comes under the Structural pattern. By using the decorator pattern we can modify the functionality of an object dynamically. The functionality of an object is extended by adding additional coverage around an object. If a number of objects are present for a single class, we can modify the behavior of a single object without affecting the other instances of the same class.
If your solution or project has below points you can consider using Decorator Pattern:
- The responsibilities need to be added or removed dynamically from an object.
- A flexible framework is required to subclass or extending functionality.
The pattern can be designed so that multiple decorators can be stacked on top of each other, each time adding a new functionality.
<Here are ALL other Java Design Patterns, explained in detail with examples>
Decorator Pattern by Example
We will understand this pattern usingthe simple concept of a Flat. At first, there will be a simple flat with one bedroom, hall, and kitchen. Later we will go on and different features to this basic flat.
Flat (Component): It is an interface which creates a blueprint for the class which will have decorators.
SimpleFlat (Concrete Component): Object for a simple flat of 1 bedroom, hall and kitchen. Extra functionality will be attached to it dynamically.
FlatDecorator(Abstract Decorator): Decorator object for SimpleFlat object. Extra functionality will be attached to it dynamically but other decorators.
Similarly, we have decorators to add facilities like modular kitchen, garden etc.
Let us see the code.
Flat.java
1 2 3 |
public interface Flat { public String getSpecification(); } |
SimpleFlat.java
1 2 3 4 5 6 7 8 |
public class SimpleFlat implements Flat { @Override public String getSpecification() { return "1BHK Flat"; } } |
Adding Furnishing Feature
1 2 3 4 5 6 7 8 9 10 11 |
public class FurnitureDecorator extends FlatDecorator { public FurnitureDecorator(Flat flat) { super(flat); } @Override public String getSpecification() { return super.getSpecification() + " + Furnishing"; } } |
Adding Kitchen Feature
1 2 3 4 5 6 7 8 9 10 11 |
public class KitchenDecorator extends FlatDecorator { public KitchenDecorator(Flat flat) { super(flat); } @Override public String getSpecification() { return super.getSpecification() + " + Modular Kitchen"; } } |
Running the Example
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
public class DecoratorDemo { public static void main(String[] args) { Flat flat = new SimpleFlat(); System.out.println(flat.getSpecification()); flat = new KitchenDecorator(new SimpleFlat()); System.out.println(flat.getSpecification()); flat = new FurnitureDecorator(new KitchenDecorator(new SimpleFlat())); System.out.println(flat.getSpecification()); flat = new GardenDecorator(new FurnitureDecorator(new KitchenDecorator(new SimpleFlat()))); System.out.println(flat.getSpecification()); flat = new FurnitureDecorator(new SimpleFlat()); System.out.println(flat.getSpecification()); } } |
Output
1 2 3 4 5 |
1BHK Flat 1BHK Flat + Modular Kitchen 1BHK Flat + Modular Kitchen + Furnishing 1BHK Flat + Modular Kitchen + Furnishing + Garden 1BHK Flat + Furnishing |
Conclusion
By using this pattern additional responsibilities are given to individual objects dynamically without affecting other objects of the same class. In short, this pattern is very flexible but at the same time code maintenance is difficult because lots of decorators we can create by using this pattern which is difficult to maintain and differentiate.
The source code is available in our Github repository.
Download Code
<Here are ALL other Java Design Patterns, explained in detail with examples>
FlatDecorator not defined? Sucks
Hi,
If you did not find it in the site, can you please download the code from GIT. It has all the files.
Appreciate!