Decorator Pattern
Real Life Example:
Take the example of a bicycle store. When someone comes to buy a bicycle, The distributor shows the basic bicycle with core functionalities. After selecting the bicycle, He asks for the accessories you want to attach. Suppose there are accessories like carrier,stand-leg,front-light,front-box,bike-bell. The service man decorates your bicycle with accessories(additional functionalities without affecting the core functionality) as per your requirement.Java Code Example:
We will try to implement the above real life example in java code by using the Inheritance and Decorator Pattern and discuss the limitation of Inheritance implementation.Inheritance Implementation
Let's first enumerate the things we have- Core Cycle
- Carrier
- Single Leg Stand
- Front Light
- Front Box
- Classic Bell
//Core Class package pattern.inherit; /** * Created by shubhamc on 18/4/17. */ public class CoreCycle { public void coreFunction(){ System.out.println("Adding Core Functions"); } } ___________________________________________________________________________ //Inherited classes package pattern.inherit; /** * Created by shubhamc on 18/4/17. */ public class CycleWithCarrier extends CoreCycle { @Override public void coreFunction(){ super.coreFunction(); addCarrier(); } public void addCarrier(){ System.out.println("Adding Carrier"); } } /*--------------------------------------------------------------*/ package pattern.inherit; /** * Created by shubhamc on 18/4/17. */ public class CycleWithClassicBell extends CoreCycle { @Override public void coreFunction(){ super.coreFunction(); addClassicBell(); } public void addClassicBell(){ System.out.println("Adding Classic Bell"); } } /*--------------------------------------------------------------*/ package pattern.inherit; /** * Created by shubhamc on 18/4/17. */ public class CycleWithFrontLight extends CoreCycle{ @Override public void coreFunction(){ super.coreFunction(); addFrontLight(); } public void addFrontLight(){ System.out.println("Adding Front Light"); } } /*--------------------------------------------------------------*/ package pattern.inherit; /** * Created by shubhamc on 18/4/17. */ public class CycleWithCarrierAndFrontLight extends CycleWithCarrier { CycleWithFrontLight obj = new CycleWithFrontLight(); @Override public void coreFunction(){ super.coreFunction(); obj.addFrontLight(); } } /*--------------------------------------------------------------*/ package pattern.inherit; /** * Created by shubhamc on 18/4/17. */ public class CycleWithCarrierAndFrontLightAndClassicBell extends CycleWithCarrierAndFrontLight { CycleWithClassicBell obj = new CycleWithClassicBell(); @Override public void coreFunction(){ super.coreFunction(); obj.addClassicBell(); } } ___________________________________________________________________________ //The main Class package pattern.inherit; /** * Created by shubhamc on 18/4/17. */ public class MainCycle { public static void main(String[] args) { //Core Cycle System.out.println("#####-Core Cycle-#####"); CoreCycle c1 = new CoreCycle(); c1.coreFunction(); System.out.println(); //Cycle with Carrier System.out.println("#####-Cycle with Carrier-#####"); CycleWithCarrier c2 = new CycleWithCarrier(); c2.coreFunction(); System.out.println(); //Cycle with Front Light System.out.println("#####-Cycle with Front Light-#####"); CycleWithFrontLight c3 = new CycleWithFrontLight(); c3.coreFunction(); System.out.println(); //Cycle with Classic Bell System.out.println("#####-Cycle with Classic Bell-#####"); CycleWithClassicBell c4 = new CycleWithClassicBell(); c4.coreFunction(); System.out.println(); //Cycle with Carrier and Front Light System.out.println("#####-Cycle with Carrier and Front Light-#####"); CycleWithCarrierAndFrontLight c5 = new CycleWithCarrierAndFrontLight(); c5.coreFunction(); System.out.println(); //Cycle with Carrier,Front Light and Classic Bell System.out.println("#####-Cycle with Carrier,Front Light and Classic Bell-#####"); CycleWithCarrierAndFrontLightAndClassicBell c6 = new CycleWithCarrierAndFrontLightAndClassicBell(); c6.coreFunction(); System.out.println(); } }By analyzing the above code We can say that There will be need of certain no. of classes for all cases. Let's do the simple math to calculate the total no. of classes.
If there is n additional accesseries then total no. of possible combinations will be
nC1 + nC2 + ...... + nCn = 2^n - 1
In this case, there are total 5 accessories, So total no. of classes will be: (2^5 - 1) = 31
Now We need to write 31 to classes to cover all cases and it will be the very cumbersome task.
Decorator Pattern Implementation
Analyze the below code and you will find that there will be only n no. of classes will be required to cover all cases for n accessories. In this case only 5 classes.___________________________________________________________________________ //The Core Interface package pattern.decorator; /** * Created by shubhamc on 18/4/17. */ public interface Cycle { void coreFunction(); } ___________________________________________________________________________ //The core Implementation package pattern.decorator; /** * Created by shubhamc on 18/4/17. */ public class CoreCycle implements Cycle { @Override public void coreFunction(){ System.out.println("Get the core Cycle"); } } ___________________________________________________________________________ //The core Abstract Decorator package pattern.decorator; /** * Created by shubhamc on 18/4/17. */ public abstract class CycleDecorator implements Cycle { private Cycle cycle; public CycleDecorator(Cycle inner){ this.cycle = inner; } @Override public void coreFunction(){ cycle.coreFunction(); } } ___________________________________________________________________________ //The Decorators package pattern.decorator; /** * Created by shubhamc on 18/4/17. */ public class CarrierDecorator extends CycleDecorator { public CarrierDecorator(Cycle inner){ super(inner); } @Override public void coreFunction(){ super.coreFunction(); decorateCarrier(); } private void decorateCarrier(){ System.out.println("Decorating Carrier"); } } /*--------------------------------------------------------------*/ package pattern.decorator; /** * Created by shubhamc on 18/4/17. */ public class ClassicBellDecorator extends CycleDecorator { public ClassicBellDecorator(Cycle inner){ super(inner); } @Override public void coreFunction(){ super.coreFunction(); decorateClassicBell(); } private void decorateClassicBell(){ System.out.println("Decorating Classic Bell"); } } /*--------------------------------------------------------------*/ package pattern.decorator; /** * Created by shubhamc on 18/4/17. */ public class FrontBoxDecorator extends CycleDecorator { public FrontBoxDecorator(Cycle inner){ super(inner); } @Override public void coreFunction(){ super.coreFunction(); decorateFrontBox(); } private void decorateFrontBox(){ System.out.println("Decorating Front Box"); } } /*--------------------------------------------------------------*/ package pattern.decorator; /** * Created by shubhamc on 18/4/17. */ public class FrontLightDecorator extends CycleDecorator { public FrontLightDecorator(Cycle inner){ super(inner); } @Override public void coreFunction(){ super.coreFunction(); decorateFrontLight(); } private void decorateFrontLight(){ System.out.println("Decorating Front Light"); } } /*--------------------------------------------------------------*/ package pattern.decorator; /** * Created by shubhamc on 19/4/17. */ public class SingleLegStandDecorator extends CycleDecorator { public SingleLegStandDecorator(Cycle inner){ super(inner); } @Override public void coreFunction(){ super.coreFunction(); decorateSingleLegStand(); } private void decorateSingleLegStand(){ System.out.println("Decorating Single Leg Stand"); } } ___________________________________________________________________________ //The main Class package pattern.decorator; /** * Created by shubhamc on 19/4/17. */ public class MainCycle { public static void main(String[] args) { //Core Cycle System.out.println("#####-Core Cycle-#####"); Cycle c1 = new CoreCycle(); c1.coreFunction(); System.out.println(); //Cycle with Carrier System.out.println("#####-Cycle with Carrier-#####"); Cycle c2 = new CarrierDecorator(new CoreCycle()); c2.coreFunction(); System.out.println(); //Cycle with Carrier and Front Light System.out.println("#####-Cycle with Carrier and Front Light-#####"); Cycle c3 = new CarrierDecorator(new FrontLightDecorator(new CoreCycle())); c3.coreFunction(); System.out.println(); //Cycle with Carrier,Front Light and Classic Bell System.out.println("#####-Cycle with Carrier,Front Light and Classic Bell-#####"); Cycle c4 = new CarrierDecorator(new FrontLightDecorator(new ClassicBellDecorator(new CoreCycle())));; c4.coreFunction(); System.out.println(); } }
Comments
Post a Comment