Friday, November 18, 2011

Decorator design Pattern in Java with Example Java Tutorial

I was thinking to write on decorator design pattern in Java when I first wrote 10 interview questions on Singleton Pattern in Java. Since design pattern is quite important while building software and it’s equally important on any Core Java Interview, It’s always good to have clear understanding of various design patterns in Java. In this article we will explore and learn Decorator Design pattern in Java which is a prominent core Java design pattern and you can see lot of its example in JDK itself. JDK use decorator pattern in IO package where it has decorated Reader and Writer Classes for various scenario, for example BufferedReader and BufferedWriter are example of decorator design pattern in Java. From design perspective its also good idea to learn how existing things work inside JDK itself for example How HashMap works in Java or How SubString method work in Java, that will give you some idea of things you need to keep in mind while designing your Class or interface in Java. Now let’s Move on to Decorator pattern in Java.

Java Decorator Design Pattern

In this Java tutorial we will see:
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

What is decorator design pattern in Java?


·          Decorator design pattern is used to enhance the functionality of a particular object at run-time or dynamically.
·          At the same time other instance of same class will not be affected by this so individual object gets the new behavior.
·          Basically we wrap the original object through decorator object.
·          Decorator design pattern is based on abstract classes and we derive concrete implementation from that classes,
·          It’s a structural design pattern and most widely used.

I prefer to answer What is decorator design pattern in point format just to stress on important point like this pattern operator at individual object level. This question also asked in many Core Java interviews in Investment banks

Problem which is solved by Decorator Pattern:

decorator design pattern java example codeNow the question is why this pattern has came into existence what is the problem with existing system, so the answer is if anyone wants to add some functionality to individual object or change the state of particular object at run time it is not possible what the possible is we can provide the specific behavior to all the object of that class at design time by the help of inheritance or using subclass, but Decorator pattern makes possible that we provide individual object of same class a specific behavior or state at run time. This doesn’t affect other object of same Class in Java.

When to use Decorator pattern in Java

·          When sub classing is become impractical and we need large number of different possibilities to make independent object or we can say we have number of combination for an object.

·          Secondly when we want to add functionality to individual object not to all object at run-time we use decorator design pattern.

Code Example of decorator design pattern:

To better understand concept of decorator design pattern let see a code example using Decorator Pattern in Java. You can also look inside JDK and find what are classes and packages which are using decorator pattern.

// Component on Decorator design pattern

public abstract class Currency {
 String description = "Unknown currency";

 public String getCurrencyDescription() {
  return description;
 }

 public abstract double cost(double value);

}


// Concrete Component

public class Rupee extends Currency {
double value;

 public Rupee() {
  description = "indian rupees";
 }

 public double cost(double v){
  value=v;
  return value;
 }

}

//Another Concrete Component

public class Dollar extends Currency{
double value;

 public Dollar () {
  description = "Dollar”;
 }

public double cost(double v){
 value=v;

  return value;

 }

}

// Decorator

public abstract class Decorator extends Currency{

 public abstract String getDescription();

}


// Concrete Decorator

public class USDDecorator extends Decorator{

 Currency currency;
 

 public USDDecorator(Currency currency){
  this.currency = currency;
 }


 public String getDescription(){
  return currency.getDescription()+" ,its US Dollar";
 }


}



//Another Concrete Decorator

public class SGDDecorator extends Decorator{
 Currency currency;

 public SGDDecorator(Currency currency){
  this.currency = currency;
 }


 public String getDescription(){
  return currency.getDescription()+" ,its singapore Dollar";
 }

}


Now its time to check currency.


public class CurrencyCheck {

 public static void main(String[] args) {

  // without adding decorators

  Currency curr = new Dollar();

  System.out.println(curr.getDescription() +" dollar. "+curr.cost(2.0));

 

 

  //adding decorators

  Currency curr2 = new USDDecorator(new Dollar());

  System.out.println(curr2.getDescription() +" dollar. "+curr2.cost(4.0));

Currency curr3 = new SGDDecorator(new Dollar());

  System.out.println(curr3.getDescription() +" dollar. "+curr3.cost(4.0));
}

Explanation of the code:

We can understand this in following term;
1.      Component Interface: In our example Currency interface is component which used on its own or we need decorator for that.
2.      Concrete Component: it implements Component and we add new behavior to this object at dynamically. Dollar and Rupee are the concrete implementation of currency.
3.      Decorator: Decorator contains a HAS a Relationship in simple word we can say it has a instance variable that holds reference for component they implement same component which they are going to decorate. Here a Decorator is an abstract class which extends the currency.
4.      Concrete Decorator: it’s an implementation of Decorator So USD Dollar and SGD Dollar are the implementation of Decorator contains instance variable for component interface or the thing which they are going to decorate.

Advantage of Decorator design Pattern in Java

In brief we see what the main advantages of using decorator design patterns are.
1.      Decorator Pattern is flexible than inheritance because inheritance add responsibilities at compile time and it will add at run-time.
2.      Decorator pattern enhance or modify the object functionality

Disadvantage

Main disadvantage of using Decorator Pattern in Java is that the code maintenance can be a problem as it provides a lot of similar kind of small objects (each decorator).

That’s all on decorator design pattern in Java. To get mastery on decorator pattern I suggest looking inside JDK library itself and finding what classes are decorated, why they are decorated. Also think of scenario where inheritance is impractical and you look more flexibility and try to use decorator pattern in Java  there.

Some more Interesting tutorials:

12 comments :

Anand said...

A Comprehensive coverage of the Decorator Pattern Javin..

Some general interview questions on J2EE Design patterns as a whole can be found by Clicking Here

Anand

Sandeep said...

Decorator has been used by JDK itself including I/O and collection classes.

Read more design patterns for interview:
Choosing Design Patterns for interview

Srishti Dubey said...

informative post indeed... I was looking for such post... I'm all new to this world and being enrolled in a core java course at http://www.wiziq.com/course/1617-core-java-for-beginners-icse-students was looking for such valuable insights.. thanks :)

Vidhya said...

decorator design pattern was tricky for me, I never really found where to use decorators. I knew it was used in Java IO package but except that I don't really find any other use of decorator pattern. is there any specific guideline or point exist which helps to decide whether to use decorator pattern or not ?

Anonymous said...

I have written the following example :

Abstrac Component :HouseComponent
Concrete Component Class :OneBedRoomHouse
Abstract Decorator :AbstractHouseDecorator
Concrete Decorator Class :OneBedRoomHouseWithCarSpaceDecorator
Concrete Decorator Class2 : OneBedRoomHouseWithSwimmingPoolDecorator

Decorator Test class : DecoratorDemo
=============================================
Abstract Component :
****************************
package com.patterns.decorator;

//This class will act as Component

public abstract class HouseComponent {

public String description=" Unknown House ";

public String getHouseDescription(){
return description;
}

public abstract Double getPrice();


}

-------------------------
Concrete Component:
****************************
package com.patterns.decorator;


public class OneBedRoomHouse extends HouseComponent{


public OneBedRoomHouse() {
description="1 BHK";
}

@Override
public Double getPrice() {
return 300000.00;
}

}

=======================
Abstract Decorator:
****************************
package com.patterns.decorator;

public abstract class AbstractHouseDecorator extends HouseComponent{

public abstract String getHouseDescription();

}
===================

Concrete Decorator class:
****************************

package com.patterns.decorator;


public class OneBedRoomHouseWithCarSpaceDecorator extends AbstractHouseDecorator{
public HouseComponent house;

public OneBedRoomHouseWithCarSpaceDecorator(HouseComponent house) {
this.house=house;
}

@Override
public String getHouseDescription() {
return house.getHouseDescription()+" with one car space";
}

@Override
public Double getPrice() {
Double modifiedPrice = house.getPrice() + house.getPrice() * .10;
return modifiedPrice;
}

}

--------------------------
concrete Decorator Class2:
****************************

package com.patterns.decorator;


public class OneBedRoomHouseWithSwimmingPoolDecorator extends
AbstractHouseDecorator {

public HouseComponent house;

public OneBedRoomHouseWithSwimmingPoolDecorator(HouseComponent house) {
this.house = house;
}

@Override
public String getHouseDescription() {
return house.getHouseDescription() + " and with swimmmingPool";

}

@Override
public Double getPrice() {
Double modifiedPrice = house.getPrice() + house.getPrice() * .25;
return modifiedPrice;
}
}

--------------------------------

Decorator Demo class:
****************************

package com.patterns.decorator;


public class DecoratorDemo {
public static void main(String[] args) {

HouseComponent oneBHKhouse = new OneBedRoomHouse();
System.out.println(oneBHKhouse.getHouseDescription()+", Price: "+oneBHKhouse.getPrice());

HouseComponent decoratedHouse1 = new OneBedRoomHouseWithCarSpaceDecorator(new OneBedRoomHouse());
System.out.println(decoratedHouse1.getHouseDescription()+", Price :"+decoratedHouse1.getPrice());


HouseComponent decoratedHouse2 =new OneBedRoomHouseWithSwimmingPoolDecorator(new OneBedRoomHouseWithCarSpaceDecorator(new OneBedRoomHouse()));
System.out.println(decoratedHouse2.getHouseDescription()+", Price :"+decoratedHouse2.getPrice());


}

}

-----------------------------------

output:

1 BHK, Price: 300000.0
1 BHK with one car space, Price :330000.0
1 BHK with one car space and with swimmmingPool, Price :412500.0

Deepak Tomar said...

In above code example, we have mention below code.
public String getDescription(){
return currency.getDescription()+" ,its US Dollar";
}
I see an error here that below line of code
return currency.getDescription()+" ,its US
should be replaced by
return currency.getCurrencyDescription()+" ,its US

Anonymous said...

SGDDecorator and USDDecorator doesn't implement the abstract methods it inherits. This code just will not compile as is.

Anonymous said...

I like the naming convention, having Decorator in the name of class, goes naming convention best practices, mentioned in Clean Code. By reading Decorator, any Java developer can recognize use of Decorator pattern.

Anonymous said...

SGDDecorator and USDDecorator doesn't implement the abstract methods it inherits. This code just will not compile as is.

Please don't post examples that don't work

Mohit said...

I agree that Decorator is one of the most useful design pattern in object oriented language, not just java. I would like to add few key things, which I feel important to understand Decorator design pattern :

- Decorator objects are part of same type hierarchy, they are decorating. For example if you are decorating Pizza then decorators like CanadianPizza, ItalianPizza or even IndianPizza will be part of same type hierarchy, either by implementing Pizza interface or extending Pizza class. This is important so that you can pass Decorator, where any method expect original object.

- You can apply more than one Decorator on Single object e.g. You can decorate your Coffee with Cream, Sugar or Milk. remember each of these decorator must be part of same type hierarchy.

- Decorator adds new behavior either before or after delegating request to the object it is decorating. For example, if we need to calculate cost of Coffe, which is decorated by Sugar and Cream than it will start from last decorator which is Cream, which delegates to Sugar, which finally delegates to Coffee, which return cost and then they add on top of that.

Beauty of this design pattern is that, it does all things at runtime, which means you have lot of flexibility on decorating your object.

Anonymous said...

Please verify and let me know if my corrections for the programs described are correct or not...

package com.decorator;

public abstract class Currency {

String description = "Unknown currency";

public String getDescription() {
return description;
}

public abstract double cost(double value);

}

package com.decorator;

public class Rupee extends Currency {

double value;

public Rupee() {
description = "Indian Rupee";
}

@Override
public double cost(double v) {
value = v;
return value;
}

}

package com.decorator;

public class Dollar extends Currency {

double value;

public Dollar() {
description = "Dollar";
}

@Override
public double cost(double v) {
value = v;
return value;
}

}


package com.decorator;

public abstract class Decorator extends Currency {

public abstract String getDescription();

}


package com.decorator;

public class USDDecorator extends Decorator {

Currency currency;

public USDDecorator(Currency currency) {
this.currency = currency;
}

@Override
public String getDescription() {
return currency.getDescription()+" ,its US Dollar";
}

@Override
public double cost(double value) {
// TODO Auto-generated method stub
return currency.cost(value);
}

}


package com.decorator;

public class SGDDecorator extends Decorator {
Currency currency;

public SGDDecorator(Currency currency) {
this.currency = currency;
}

public String getDescription() {
return currency.getDescription() + " ,its singapore Dollar";
}

@Override
public double cost(double value) {
// TODO Auto-generated method stub
return currency.cost(value);
}
}


package com.decorator;

public class CurrencyCheck {

public static void main(String[] args) {

// without adding decorators

Currency curr = new Dollar();
System.out.println(curr.getDescription() + " dollar. " +curr.cost(2.0));

// adding decorators
Currency curr2 = new USDDecorator(new Dollar());
System.out.println(curr2.getDescription() + " dollar. "+curr2.cost(4.0));

Currency curr3 = new SGDDecorator(new Dollar());
System.out.println(curr3.getDescription() + " dollar. "+curr3.cost(4.0));

}
}


Output
--------------
Dollar dollar. 2.0
Dollar ,its US Dollar dollar. 4.0
Dollar ,its singapore Dollar dollar. 4.0


Please comment.

Nikhil said...

Javin, extremely excellent article. I have cleared many of my concepts from this article. Thanks a lot. Nikhil

Post a Comment