What is Decorator Design Pattern?
Decorator Design Pattern is intended to add new functionality to an already existing object without modifying its structure. Decorator Design Pattern involves creation of decorator class that will wrap original class within itself and add additional functionality in the decorator class thereby keeping the signature of original class methods intact. That’s the reason why Decorator class is also termed as “Wrapper”. For example, if we have created 10 objects among which we need to provide additional behavior for just 2 objects among those ten, then we can achieve it using Decorator Pattern.
Design patterns suggest that the Decorator class has to be an abstract class which is then inherited by concrete classes and these concrete classes have to implement the additional behavior.
Purpose of Decorator Design Pattern
Intended purpose of Decorator Design Pattern is to dynamically append additional responsibilities to an existing object.
Decorator Design Pattern Implementation using Java
To demonstrate Decorator Design Pattern, we will consider the shape example. There is an iShape interface that is implemented by two concrete classes namely Square and Rectangle. The iShape interface has a drawShape method which can be overridden by concrete classes to display what shape is being drawn.
Now we have to decorate the shape by giving yellow color for the borders. In order to add this new functionality to the shapes, we do not modify the iShape interface or its associated concrete classes. Instead we create a decorator class which incorporates this additional functionality and the decorator class wraps the shape interface objects within itself.
This scenario is implemented through the code shown below:
Creation of iShape interface with drawShape method:
1 2 3 |
public interface iShape { public void drawShape(); } |
Creation of concrete classes Rectangle and Square that implements the iShape interface and overrides the drawShape method of iShape interface:
1 2 3 4 5 6 7 |
public class Rectangle implements iShape { @Override public void drawShape(){ System.out.println("Currently drawing Rectangle Shape"); } } |
1 2 3 4 5 6 7 |
public class Square implements iShape { @Override public void drawShape(){ System.out.println("Currently drawing Square Shape"); } } |
Now comes the creation of abstract decorator class that implements the iShape interface:
1 2 3 4 5 6 7 8 9 10 11 |
public abstract class DecoratorForShape implements iShape { protected iShape shapeToBeDecorated; public DecoratorForShape(iShape shapeToBeDecorated){ this.shapeToBeDecorated = shapeToBeDecorated; } public void drawShape(){ shapeToBeDecorated.drawShape(); } } |
The next step is the creation of concrete class that inherits from DecoratorForShape class. This concrete class is called YellowShapeDecorator and its intention is to color the shape object’s border in yellow color.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
public class YellowShapeDecorator extends DecoratorForShape{ public YellowShapeDecorator(iShape shapeToBeDecorated){ super(shapeToBeDecorated); } @Override public void drawShape(){ shapeToBeDecorated.drawShape(); setYellowBorder(shapeToBeDecorated); } private void setYellowBorder(iShape shapeToBeDecorated){ System.out.println("Border color of the Shape is Yellow"); } } |
Now let us test if the decorator class is working fine by writing a test class as shown below:
1 2 3 4 5 6 7 8 9 10 |
public class TestDecoratorPattern { public static void main(String[] args) { iShape squareObj = new Square(); squareObj.drawShape(); iShape yellowBorderSquare = new YellowShapeDecorator(new Square()); yellowBorderSquare.drawShape(); iShape yellowBorderRectangle = new YellowShapeDecorator(new Rectangle()); yellowBorderRectangle.drawShape(); } } |
Output will be:
Currently drawing Square Shape
Currently drawing Square Shape
Border color of the Shape is Yellow
Currently drawing Rectangle Shape
Border color of the Shape is Yellow
Leave a Reply