Decorator Pattern

What is Decorator Pattern?

The decorator pattern helps to add behavior or responsibilities to an object dynamically. This is also known as “Wrapper”. Decorators provide a flexible alternative to subclassing for extending functionality.

Allows for the dynamic wrapping of objects in order to modify their existing responsibilities and behaviours

Where to use ?

The decorator pattern can be use wherever there is a need to add some functionality to the object or group of objects.
Sometimes we want to add responsibilities to individual objects, not to an entire class. For
example a graphical user interface toolkit should let you add properties like borders or
behaviors like scrolling to any user interface component.

Traditionally, you might consider subclassing to be the best way to approach this – but there will be cases that subclassing isn’t possible, or is impractical. This leads us to the Open/Closed Principle: classes should be open for extension, but closed for modification. This is a good principle to keep in mind, as it keeps your class stable, but leaves it open for extension if someone wants to add behaviour.

 

Implementation

The figure below shows a UML class diagram for the Decorator Pattern:
Decorator Pattern Implementation - UML Class Diagram

The participants classes in the decorator pattern are:

  • Component – Interface for objects that can have responsibilities added to them dynamically.
  • ConcreteComponent – Defines an object to which additional responsibilities can be added.
  • Decorator – Maintains a reference to a Component object and defines an interface that conforms to Component’s interface.
  • Concrete Decorators – Concrete Decorators extend the functionality of the component by adding state or adding behavior.

 

Now lets see an implement with the help of Cars – we will define an interface Car to define the assemble method and then we can have a Basic car, further more we can extend it to  Sedan Car or Hatchback Car.
Component Interface – The interface or abstract class defining the methods that will be implemented.

Lets take Car as a component interface.
Car.java

 

Component Implementation – The BasicCar class as our component implementation.

BasicCar.java

 

Decorator – Decorator class implements the component interface and it has a HAS-A relationship with the component interface. The component variable should be accessible to the child decorator classes, so it should be protected.

CarDecorator.java

Concrete Decorators – Extending the base decorator functionality and modifying the component behaviour accordingly. We can have concrete decorator classes as SedanCar and HatchBackCar.

SedanCar.java

 

HatchBackCar.java

Decorator Pattern Client Program for testing.

DecoratorPatternTest.java

Output of above test program is:

Basic Car. Adding features of SedanCar Car.
Basic Car. Adding features of HatchBackCar Car.

Key things about Decorator Design Pattern

Now, we have seen an example of decorator pattern in Java, we can quickly summarize few important things which are worth remembering while implementing or applying decorator pattern or even to answers design pattern questions like When to use Decorator design pattern in Java.

1) Decorator must be of same type of object, which they are decorating. This can be achieved either by implementing interface of object, or by extending abstract class of original class.

2) Decorator is based on Composition, which means it needs original object to decorate it. This is achieved by creating constructor on decorator class which accept a base type of original object. e.g. in this example constructor of CheeseDecorator accepts Sandwich object. Decorator pattern is also a good example of Open Closed Design Principle, which is one of the key principle from Uncle Bob’s SOLID design principles.

3) Decorator class adds new functionality before or after delegating task to original object. In this example, price of Decorator i.e. cheese is included after calculating price of White Bread Sandwich.

4) Remember, Decorator design pattern only affects objects at runtime, it doesn’t affect class. You should use DECORATOR PATTERN when your intent is to add new functionality at runtime (i.e. a customer order, where you only know about order details, one it placed).

5) There is one disadvantage of Decorator pattern as well,

Drawback:
It adds lots of small classes in code base, remember overwhelming number of classes in java.io package. Though, once you know that which classes are main classes, and which are decorators, you tend to get better understanding of overall structure. UML diagrams certain helps in this case.

Code debugging might be difficult since this pattern adds functionality at runtime

 

Questions on Decorator pattern

  • What is decorator pattern in Java?
  • When to use decorator pattern in Java?
  • How to use decorator pattern in Java?
  • Example of decorator design pattern
  • Advantage and Disadvantage of decorator pattern in Java
   

Comments are closed