Decorator Pattern Java(System Design)
Suppose you have a class.It have some responsibilities and it can be decorated by adding some decoration. In that case Decorator Pattern need.
Assume an example,
Like I have a Ice-cream.I need Mango Flavour with Vanilla Flavour.
The total price will different with adding that flavour cost also right.
Therefore,Decorator Design Pattern also same like that
Basically a class(IceCream) is extensible but not modifiable.So that class extends a main (Flavour)decorator Class .That Decorator class will be extensible to their sub/child (Lichi/Mango/Vanilla)class.
Let’s understand the Decorator Pattern
- Component(Ex: IceCream): The Component defines the interface for any objects that have some responsibilities and can be added dynamically
- ConcreteComponent(Ex: CupIceCream/ConeIceCream): It is simply an implementation of Component interface
- Decorator(Ex: ToppingsDecorator): The Decorator has a reference to a Component, and also conforms to the Component interface. Decorator is essentially wrapping the Component
- ConcreteDecorator(VanillaFlavour/MangoFlavour): The ConcreteDecorator just adds responsibilities to the original Component.
BaseIceCream.java
package IceCreams;
public abstract class BaseIceCream {
public abstract int cost();
}
ConeIceCream.java
package IceCreams;
public class ConeIceCream extends BaseIceCream {
@Override
public int cost() {
return 45;
}
}
ToppingsDecorator.java
package Flavours;
import IceCreams.BaseIceCream;
public abstract class ToppingsDecorator extends BaseIceCream {
}
LichiFlavour.java
package Flavours;
import IceCreams.BaseIceCream;
public class LichiFlavour extends ToppingsDecorator{
BaseIceCream iceCream;
public LichiFlavour(BaseIceCream iceCream){
this.iceCream = iceCream;
}
@Override
public int cost(){
return 25+iceCream.cost();
}
}
MangoFlavour.java
package Flavours;
import IceCreams.BaseIceCream;
public class MangoFlavour extends ToppingsDecorator{
BaseIceCream iceCream;
public MangoFlavour(BaseIceCream iceCream){
this.iceCream = iceCream;
}
@Override
public int cost(){
return 20+iceCream.cost();
}
}
VanillaFlavour.java
package Flavours;
import IceCreams.BaseIceCream;
public class VanillaFlavour extends ToppingsDecorator {
BaseIceCream iceCream;
public VanillaFlavour(BaseIceCream iceCream){
this.iceCream = iceCream;
}
@Override
public int cost(){
return 30+iceCream.cost();
}
}
Main.java
import IceCreams.BaseIceCream;
import IceCreams.ConeIceCream;
import Flavours.LichiFlavour;
import Flavours.MangoFlavour;
import Flavours.VanillaFlavour;
public class Main {
public static void main(String[] args) {
BaseIceCream iceCream1 = new MangoFlavour(new LichiFlavour(new ConeIceCream()));
System.out.println("Cost of IceCream is: "+iceCream1.cost());
BaseIceCream iceCream2 = new LichiFlavour(new VanillaFlavour(new ConeIceCream()));
System.out.println("Cost of IceCream is: "+iceCream2.cost());
}
}
Output:
Use cases of Decorator Design Pattern:
- Car Design
- Pizza Decoration
- Coffee base System Decoration