opencodez

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 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 Code

x

xHere are ALL other Java Design Patterns, explained in detail with examplesx

x