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.
xHere are ALL other Java Design Patterns, explained in detail with examplesx
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
public interface Flat { public String getSpecification(); }
SimpleFlat.java
public class SimpleFlat implements Flat { @Override public String getSpecification() { return "1BHK Flat"; } }
Adding Furnishing Feature
public class FurnitureDecorator extends FlatDecorator { public FurnitureDecorator(Flat flat) { super(flat); } @Override public String getSpecification() { return super.getSpecification() + " + Furnishing"; } }
Adding Kitchen Feature
public class KitchenDecorator extends FlatDecorator { public KitchenDecorator(Flat flat) { super(flat); } @Override public String getSpecification() { return super.getSpecification() + " + Modular Kitchen"; } }
Running the Example
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
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 Codex
xHere are ALL other Java Design Patterns, explained in detail with examplesx
x