In this article, we will go through Decorator design pattern. We will also see a sample implementation in Java.
Decorator Design Pattern
The Decorator pattern adds responsibilities to an object without modifying the object itself.
When we have need for additional functionalities for an existing object, we can consider using this pattern. It suggests creating a decorator class that wraps the original class and provides required additional functionality.
Now, we can use the original class or the decorated class with additional features.
Let’s provide an example of Decorator implementation in Java.
Here, we have a ConcreteComponent class that extends Component abstract class. We will create a decorator to add extra features to the ConcreteComponent class.
Create Abstract Component
package com.topjavatutorial.patterns.decorator; public abstract class Component { public abstract void doSomething(); }
Create Concrete Components
package com.topjavatutorial.patterns.decorator; public class ConcreteComponent extends Component { @Override public void doSomething() { System.out.println("Original Component Functionalities"); } }
Create Abstract Decorator
Decorators have the same super type as the object they decorate. So, lets extend the Component class in the decorator.
package com.topjavatutorial.patterns.decorator; public abstract class Decorator extends Component { Component comp; public Decorator(Component comp){ this.comp = comp; } @Override public void doSomething(){ comp.doSomething(); } }
Create Concrete Decorator(s)
We can add one or more decorators. Let’s just create one for simplicity.
package com.topjavatutorial.patterns.decorator; public class ConcreteDecorator extends Decorator { public ConcreteDecorator(Component comp){ super(comp); } public void doSomething() { super.doSomething(); System.out.println("Performing Additional functionalities in Concrete Decorator"); } }
Here, we are executing base component functionality followed by decorator functionality, but we can do the other way too.
Decorators can add their functionality before or after the original object’s functionality.
Testing our Decorator Pattern implementation
package com.topjavatutorial.patterns.decorator; public class DecoratorDemo { public static void main(String[] args) { Component component = new ConcreteComponent(); ConcreteDecorator decoratedComponent = new ConcreteDecorator(component); decoratedComponent.doSomething(); } }
Output
Original Component Functionalities
Performing Additional functionalities in Concrete Decorator
Decorators in Java API
BufferedInputStream acts as a Decorator for the FileInputStream. BufferedInputStream adds buffer functionality to improve performance and provides a readLine() method to read character based data line by line.
Similarly, BufferedReader works as a Decorator for FileReader.
Decorator Design Pattern Advantages
Decorators allow behavior to be extended without modifying existing code. This conforms to Open-Closed principle which says, Classes should be open for extension, but closed for modification.
Read more about Open-Closed principle.
Decorators provide an alternative to sub-classing for extending behavior.
Decorators allow behavior modification at runtime rather than going back into existing code and making changes.
Decorator Design Pattern Disadvantages
Decorators can result in several small objects in the design.
Overusing decorators can make the system difficult to maintain and unnecessarily complex.
You may also like the following articles on design patterns :
Factory Pattern in Java
Abstract Factory Pattern in Java
Observer Design Pattern in Java
Reference books
Head First Object-Oriented Analysis and Design
© 2016, https:. All rights reserved. On republishing this post, you must provide link to original post
#