Other Tutorials

Decorator Design Pattern In Java

Introduction:

A decorator design pattern allows dynamically attaching the additional responsibilities or behaviors to an object at runtime. It is a structural pattern and makes use of aggregation to combine those behaviors.

In this tutorial, we’ll learn to implement the decorator pattern.

UML Diagram:

Let’s start by looking at the UML representation of a decorator pattern:Decorator Design Pattern

The ConcreteComponent class is the one for which we’ll like add additional behaviors at runtime. The ConcreteDecorator1, ConcreteDecorator2, … are the decorator classes which hold the logic to decorate a given Component.

Note that the abstract Decorator classhas a Component. In other words, it aggregates any other type of component which allows us to stack components one on the top of the other.

Moreover, both the ConcreteComponent and Decorator classes implement a common interface – Component.

Example Implementation:

Let’s say we are selling a gift item. Once a user selects a gift item, there can be multiple ways just to decorate that gift item say with a red or a blue ribbon, purple or green gift wrap, etc.

Rather than creating a class for each possible combination, it’s a good idea to implement it using a decorator pattern.

So, let’s create our GiftComponent interface:

Also, let’s write our GiftItem class which is a concrete implementation of the GiftComponent:

Implementing Abstract Decorator:

Now that we have a GiftItem that we’ll like to decorate, let’s define our abstract GiftDecorator class:

The gift decorator has a single instance of the gift component. This enables stacking decorators on top of one another.

Creating Multiple Decorators:

Finally, we can create as many custom decorators as we want.

Let’s create a few gift wraps:

And a few types of ribbons for further decoration:

Testing Our Implementation:

Let’s now test out our implementation to see what happens:

As we can see, we are now able to easily and elegantly wrap the gift item in the way we want just by chaining the decorators. The above code will print:

Conclusion:

The decorator design pattern uses aggregation as a substitute for a pure inheritance. It allows us to dynamically add behaviors to an object. It takes away the overhead of creating a separate class for every possible combination thereby significantly reducing the number of classes.

Also, it adheres to the Single Responsibility Principle which states that every class must exactly do one thing. The classes like java.io.BufferedReader, java.io.FileReader are designed using the decorator design pattern.

Be the First to comment.

Leave a Comment

Your email address will not be published. Required fields are marked *