DESIGNPATTERNQUICKGUIDEhttp://www.tutorialspoint.com/design_pattern/design_pattern_quick_guide.htm
Copyrighttutorialspoint.com
Designpatternsrepresentthebestpracticesusedbyexperiencedobjectorientedsoftwaredevelopers.Designpatternsaresolutionstogeneralproblemsthatsoftwaredevelopersfacedduringsoftwaredevelopment.Thesesolutionswereobtainedbytrialanderrorbynumeroussoftwaredevelopersoverquiteasubstantialperiodoftime.
WhatisGangofFourGOF ?In1994,fourauthorsErichGamma,RichardHelm,RalphJohnsonundJohnVlissidespublishedabooktitledDesignPatternsElementsofReusableObjectOrientedSoftwarewhichinitiatedtheconceptofDesignPatterninSoftwaredevelopment.TheseauthorsarecollectivelyknownasGangofFour GOF .Accordingtotheseauthorsdesignpatternsareprimarilybasedonthefollowingprinciplesofobjectorientateddesign.ProgramtoaninterfacenotanimplementationFavorobjectcompositionoverinheritance
UsageofDesignPatternDesignPatternshavetwomainusagesinsoftwaredevelopment.
CommonplatformfordevelopersDesignpatternsprovideastandardterminologyandarespecifictoparticularscenario.Forexample,asingletondesignpatternsignifiesuseofsingleobjectsoalldevelopersfamiliarwithsingledesignpatternwillmakeuseofsingleobjectandtheycantelleachotherthatprogramisfollowingasingletonpattern.
BestPracticesDesignpatternshavebeenevolvedoveralongperiodoftimeandtheyprovidebestsolutionstocertainproblemsfacedduringsoftwaredevelopment.Learningthesepatternshelpsunexperienceddeveloperstolearnsoftwaredesigninaneasyandfasterway.
TypesofDesignPatternAsperthedesignpatternreferencebookDesignPatternsElementsofReusableObjectOrientedSoftware,thereare23designpatterns.Thesepatternscanbeclassifiedinthreecategories:Creational,Structuralandbehavioralpatterns.We'llalsodiscussanothercategoryofdesignpatterns:J2EEdesignpatterns.
S.N.
Pattern&Description
1
CreationalPatternsThesedesignpatternsprovideswaytocreateobjectswhilehidingthecreationlogic,ratherthaninstantiatingobjectsdirectlyusingnewopreator.Thisgivesprogrammoreflexibilityindecidingwhichobjectsneedtobecreatedforagivenusecase.
2
StructuralPatternsThesedesignpatternsconcernclassandobjectcomposition.Conceptofinheritanceisusedtocomposeinterfacesanddefinewaystocomposeobjectstoobtainnewfunctionalities.
3
BehavioralPatternsThesedesignpatternsarespecificallyconcernedwithcommunicationbetweenobjects.
4
J2EEPatternsThesedesignpatternsarespecificallyconcernedwiththepresentationtier.ThesepatternsareidentifiedbySunJavaCenter.
FACTORYPATTERNFactorypatternisoneofmostuseddesignpatterninJava.Thistypeofdesignpatterncomesundercreationalpatternasthispatternprovidesoneofthebestwaystocreateanobject.InFactorypattern,wecreateobjectwithoutexposingthecreationlogictotheclientandrefertonewlycreatedobjectusingacommoninterface.
ImplementationWe'regoingtocreateaShapeinterfaceandconcreteclassesimplementingtheShapeinterface.AfactoryclassShapeFactoryisdefinedasanextstep.FactoryPatternDemo,ourdemoclasswilluseShapeFactorytogetaShapeobject.Itwillpassinformation(CIRCLE/RECTANGLE/SQUARE)toShapeFactorytogetthetypeofobjectitneeds.
Step1Createaninterface.Shape.javapublicinterfaceShape{voiddraw();}
Step2Createconcreteclassesimplementingthesameinterface.Rectangle.javapublicclassRectangleimplementsShape{@Overridepublicvoiddraw(){System.out.println("InsideRectangle::draw()method.");}}
Square.javapublicclassSquareimplementsShape{@Overridepublicvoiddraw(){System.out.println("InsideSquare::draw()method.");}}
Circle.javapublicclassCircleimplementsShape{@Overridepublicvoiddraw(){System.out.println("InsideCircle::draw()method.");}}
Step3CreateaFactorytogenerateobjectofconcreteclassbasedongiveninformation.ShapeFactory.javapublicclassShapeFactory{//usegetShapemethodtogetobjectoftypeshapepublicShapegetShape(StringshapeType){if(shapeType==null){returnnull;}if(shapeType.equalsIgnoreCase("CIRCLE")){returnnewCircle();}elseif(shapeType.equalsIgnoreCase("RECTANGLE")){returnnewRectangle();}elseif(shapeType.equalsIgnoreCase("SQUARE")){returnnewSquare();
}returnnull;}}
Step4UsetheFactorytogetobjectofconcreteclassbypassinganinformationsuchastype.FactoryPatternDemo.javapublicclassFactoryPatternDemo{publicstaticvoidmain(String[]args){ShapeFactoryshapeFactory=newShapeFactory();//getanobjectofCircleandcallitsdrawmethod.Shapeshape1=shapeFactory.getShape("CIRCLE");//calldrawmethodofCircleshape1.draw();//getanobjectofRectangleandcallitsdrawmethod.Shapeshape2=shapeFactory.getShape("RECTANGLE");//calldrawmethodofRectangleshape2.draw();//getanobjectofSquareandcallitsdrawmethod.Shapeshape3=shapeFactory.getShape("SQUARE");//calldrawmethodofcircleshape3.draw();}}
Step5Verifytheoutput.InsideCircle::draw()method.InsideRectangle::draw()method.InsideSquare::draw()method.
ABSTRACTFACTORYPATTERNAbstractFactorypatternsworksaroundasuperfactorywhichcreatesotherfactories.ThisfactoryisalsocalledasFactoryoffactories.Thistypeofdesignpatterncomesundercreationalpatternasthispatternprovidesoneofthebestwaystocreateanobject.InAbstractFactorypatternaninterfaceisresponsibleforcreatingafactoryofrelatedobjects,withoutexplicitlyspecifyingtheirclasses.EachgeneratedfactorycangivetheobjectsaspertheFactorypattern.
ImplementationWe'regoingtocreateaShapeandColorinterfacesandconcreteclassesimplementingtheseinterfaces.WecreatesanabstractfactoryclassAbstractFactoryasnextstep.FactoryclassesShapeFactoryandColorFactoryaredefinedwhereeachfactoryextendsAbstractFactory.Afactorycreator/generatorclassFactoryProduceriscreated.AbstractFactoryPatternDemo,ourdemoclassusesFactoryProducertogetaAbstractFactoryobject.Itwillpassinformation(CIRCLE/RECTANGLE/SQUAREforShape)toAbstractFactorytogetthetypeofobjectitneeds.Italsopassesinformation(RED/GREEN/BLUEforColor)toAbstractFactorytogetthetypeofobjectitneeds.
Step1CreateaninterfaceforShapes.Shape.javapublicinterfaceShape{voiddraw();}
Step2Createconcreteclassesimplementingthesameinterface.Rectangle.javapublicclassRectangleimplementsShape{@Overridepublicvoiddraw(){System.out.println("InsideRectangle::draw()method.");}}
Square.javapublicclassSquareimplementsShape{@Overridepublicvoiddraw(){System.out.println("InsideSquare::draw()method.");}}
Circle.javapublicclassCircleimplementsShape{@Overridepublicvoiddraw(){System.out.println("InsideCircle::draw()method.");}}
Step3CreateaninterfaceforColors.Color.javapublicinterfaceColor{voidfill();}
Step4
Createconcreteclassesimplementingthesameinterface.Red.javapublicclassRedimplementsColor{@Overridepublicvoidfill(){System.out.println("InsideRed::fill()method.");}}
Green.javapublicclassGreenimplementsColor{@Overridepublicvoidfill(){System.out.println("InsideGreen::fill()method.");}}
Blue.javapublicclassBlueimplementsColor{@Overridepublicvoidfill(){System.out.println("InsideBlue::fill()method.");}}
Step5CreateanAbstractclasstogetfactoriesforColorandShapeObjects.AbstractFactory.javapublicabstractclassAbstractFactory{abstractColorgetColor(Stringcolor);abstractShapegetShape(Stringshape);}
Step6CreateFactoryclassesextendingAbstractFactorytogenerateobjectofconcreteclassbasedongiveninformation.ShapeFactory.javapublicclassShapeFactoryextendsAbstractFactory{@OverridepublicShapegetShape(StringshapeType){if(shapeType==null){returnnull;}if(shapeType.equalsIgnoreCase("CIRCLE")){returnnewCircle();}elseif(shapeType.equalsIgnoreCase("RECTANGLE")){returnnewRectangle();}elseif(shapeType.equalsIgnoreCase("SQUARE")){returnnewSquare();}returnnull;}@OverrideColorgetColor(Stringcolor){returnnull;}}
ColorFactory.javapublicclassColorFactoryextendsAbstractFactory{@OverridepublicShapegetShape(StringshapeType){returnnull;}@OverrideColorgetColor(Stringcolor){if(color==null){returnnull;
}if(color.equalsIgnoreCase("RED")){returnnewRed();}elseif(color.equalsIgnoreCase("GREEN")){returnnewGreen();}elseif(color.equalsIgnoreCase("BLUE")){returnnewBlue();}returnnull;}}
Step7CreateaFactorygenerator/producerclasstogetfactoriesbypassinganinformationsuchasShapeorColorFactoryProducer.javapublicclassFactoryProducer{publicstaticAbstractFactorygetFactory(Stringchoice){if(choice.equalsIgnoreCase("SHAPE")){returnnewShapeFactory();}elseif(choice.equalsIgnoreCase("COLOR")){returnnewColorFactory();}returnnull;}}
Step8UsetheFactoryProducertogetAbstractFactoryinordertogetfactoriesofconcreteclassesbypassinganinformationsuchastype.AbstractFactoryPatternDemo.javapublicclassAbstractFactoryPatternDemo{publicstaticvoidmain(String[]args){//getshapefactoryAbstractFactoryshapeFactory=FactoryProducer.getFactory("SHAPE");//getanobjectofShapeCircleShapeshape1=shapeFactory.getShape("CIRCLE");//calldrawmethodofShapeCircleshape1.draw();//getanobjectofShapeRectangleShapeshape2=shapeFactory.getShape("RECTANGLE");//calldrawmethodofShapeRectangleshape2.draw();//getanobjectofShapeSquareShapeshape3=shapeFactory.getShape("SQUARE");//calldrawmethodofShapeSquareshape3.draw();//getcolorfactoryAbstractFactorycolorFactory=FactoryProducer.getFactory("COLOR");//getanobjectofColorRedColorcolor1=colorFactory.getColor("RED");//callfillmethodofRedcolor1.fill();//getanobjectofColorGreenColorcolor2=colorFactory.getColor("Green");//callfillmethodofGreencolor2.fill();//getanobjectofColorBlueColorcolor3=colorFactory.getColor("BLUE");//callfillmethodofColorBluecolor3.fill();}}
Step9Verifytheoutput.InsideCircle::draw()method.
InsideRectangle::draw()method.InsideSquare::draw()method.InsideRed::fill()method.InsideGreen::fill()method.InsideBlue::fill()method.
SINGLETONPATTERNSingletonpatternisoneofthesimplestdesignpatternsinJava.Thistypeofdesignpatterncomesundercreationalpatternasthispatternprovidesoneofthebestwaytocreateanobject.Thispatterninvolvesasingleclasswhichisresponsibletocreatesownobjectwhilemakingsurethatonlysingleobjectgetcreated.Thisclassprovidesawaytoaccessitsonlyobjectwhichcanbeaccesseddirectlywithoutneedtoinstantiatetheobjectoftheclass.
ImplementationWe'regoingtocreateaSingleObjectclass.SingleObjectclasshaveitsconstructorasprivateandhaveastaticinstanceofitself.SingleObjectclassprovidesastaticmethodtogetitsstaticinstancetooutsideworld.SingletonPatternDemo,ourdemoclasswilluseSingleObjectclasstogetaSingleObjectobject.
Step1CreateaSingletonClass.SingleObject.javapublicclassSingleObject{//createanobjectofSingleObjectprivatestaticSingleObjectinstance=newSingleObject();//maketheconstructorprivatesothatthisclasscannotbe//instantiatedprivateSingleObject(){}//GettheonlyobjectavailablepublicstaticSingleObjectgetInstance(){returninstance;}publicvoidshowMessage(){System.out.println("HelloWorld!");}}
Step2Gettheonlyobjectfromthesingletonclass.SingletonPatternDemo.javapublicclassSingletonPatternDemo{publicstaticvoidmain(String[]args){//illegalconstruct//CompileTimeError:TheconstructorSingleObject()isnotvisible//SingleObjectobject=newSingleObject();
//GettheonlyobjectavailableSingleObjectobject=SingleObject.getInstance();//showthemessageobject.showMessage();}}
Step3Verifytheoutput.HelloWorld!
BUILDERPATTERNBuilderpatternbuildsacomplexobjectusingsimpleobjectsandusingastepbystepapproach.Thistypeofdesignpatterncomesundercreationalpatternasthispatternprovidesoneofthebestwaystocreateanobject.ABuilderclassbuildsthefinalobjectstepbystep.Thisbuilderisindependentofotherobjects.
ImplementationWe'veconsideredabusinesscaseoffastfoodrestaurantwhereatypicalmealcouldbeaburgerandacolddrink.BurgercouldbeeitheraVegBurgerorChickenBurgerandwillbepackedbyawrapper.Colddrinkcouldbeeitheracokeorpepsiandwillbepackedinabottle.We'regoingtocreateanIteminterfacerepresentingfooditemssuchasburgersandcolddrinksandconcreteclassesimplementingtheIteminterfaceandaPackinginterfacerepresentingpackagingoffooditemsandconcreteclassesimplementingthePackinginterfaceasburgerwouldbepackedinwrapperandcolddrinkwouldbepackedasbottle.WethencreateaMealclasshavingArrayListofItemandaMealBuildertobuilddifferenttypesofMealobjectbycombiningItem.BuilderPatternDemo,ourdemoclasswilluseMealBuildertobuildaMeal.
Step1CreateaninterfaceItemrepresentingfooditemandpacking.Item.javapublicinterfaceItem{publicStringname();publicPackingpacking();publicfloatprice();}
Packing.javapublicinterfacePacking{publicStringpack();}
Step2CreateconcreateclassesimplementingthePackinginterface.Wrapper.java
publicclassWrapperimplementsPacking{@OverridepublicStringpack(){return"Wrapper";}}
Bottle.javapublicclassBottleimplementsPacking{@OverridepublicStringpack(){return"Bottle";}}
Step3Createabstractclassesimplementingtheiteminterfaceprovidingdefaultfunctionalities.Burger.javapublicabstractclassBurgerimplementsItem{@OverridepublicPackingpacking(){returnnewWrapper();}@Overridepublicabstractfloatprice();}
ColdDrink.javapublicabstractclassColdDrinkimplementsItem{@OverridepublicPackingpacking(){returnnewBottle();}}
@Overridepublicabstractfloatprice();
Step4CreateconcreteclassesextendingBurgerandColdDrinkclassesVegBurger.javapublicclassVegBurgerextendsBurger{@Overridepublicfloatprice(){return25.0f;}@OverridepublicStringname(){return"VegBurger";}}
ChickenBurger.javapublicclassChickenBurgerextendsBurger{@Overridepublicfloatprice(){return50.5f;}@OverridepublicStringname(){return"ChickenBurger";}}
Coke.java
publicclassCokeextendsColdDrink{@Overridepublicfloatprice(){return30.0f;}@OverridepublicStringname(){return"Coke";}}
Pepsi.javapublicclassPepsiextendsColdDrink{@Overridepublicfloatprice(){return35.0f;}@OverridepublicStringname(){return"Pepsi";}}
Step5CreateaMealclasshavingItemobjectsdefinedabove.Meal.javaimportjava.util.ArrayList;importjava.util.List;publicclassMeal{privateListitems=newArrayList();publicvoidaddItem(Itemitem){items.add(item);}publicfloatgetCost(){floatcost=0.0f;for(Itemitem:items){cost+=item.price();}returncost;}publicvoidshowItems(){for(Itemitem:items){System.out.print("Item:"+item.name());System.out.print(",Packing:"+item.packing().pack());System.out.println(",Price:"+item.price());}}}
Step6CreateaMealBuilderclass,theactualbuilderclassresponsibletocreateMealobjects.MealBuilder.javapublicclassMealBuilder{publicMealprepareVegMeal(){Mealmeal=newMeal();meal.addItem(newVegBurger());meal.addItem(newCoke());returnmeal;}publicMealprepareNonVegMeal(){Mealmeal=newMeal();meal.addItem(newChickenBurger());meal.addItem(newPepsi());returnmeal;}}
Step7
BuiderPatternDemousesMealBuidertodemonstratebuilderpattern.BuilderPatternDemo.javapublicclassBuilderPatternDemo{publicstaticvoidmain(String[]args){MealBuildermealBuilder=newMealBuilder();MealvegMeal=mealBuilder.prepareVegMeal();System.out.println("VegMeal");vegMeal.showItems();System.out.println("TotalCost:"+vegMeal.getCost());MealnonVegMeal=mealBuilder.prepareNonVegMeal();System.out.println("\n\nNonVegMeal");nonVegMeal.showItems();System.out.println("TotalCost:"+nonVegMeal.getCost());}}
Step8Verifytheoutput.VegMealItem:VegBurger,Packing:Wrapper,Price:25.0Item:Coke,Packing:Bottle,Price:30.0TotalCost:55.0NonVegMealItem:ChickenBurger,Packing:Wrapper,Price:50.5Item:Pepsi,Packing:Bottle,Price:35.0TotalCost:85.5
PROTOTYPEPATTERNPrototypepatternreferstocreatingduplicateobjectwhilekeepingperformanceinmind.Thistypeofdesignpatterncomesundercreationalpatternasthispatternprovidesoneofthebestwaytocreateanobject.Thispatterninvolvesimplementingaprototypeinterfacewhichtellstocreateacloneofthecurrentobject.Thispatternisusedwhencreationofobjectdirectlyiscostly.Forexample,aobjectistobecreatedafteracostlydatabaseoperation.Wecancachetheobject,returnsitscloneonnextrequestandupdatethedatabaseasasandwhenneededthusreducingdatabasecalls.
ImplementationWe'regoingtocreateanabstractclassShapeandconcreteclassesextendingtheShapeclass.AclassShapeCacheisdefinedasanextstepwhichstoresshapeobjectsinaHashtableandreturnstheirclonewhenrequested.PrototypPatternDemo,ourdemoclasswilluseShapeCacheclasstogetaShapeobject.
Step1CreateanabstractclassimplementingClonableinterface.Shape.javapublicabstractclassShapeimplementsCloneable{privateStringid;protectedStringtype;
abstractvoiddraw();publicStringgetType(){returntype;}publicStringgetId(){returnid;}publicvoidsetId(Stringid){this.id=id;}publicObjectclone(){Objectclone=null;try{clone=super.clone();}catch(CloneNotSupportedExceptione){e.printStackTrace();}returnclone;}}
Step2Createconcreteclassesextendingtheaboveclass.Rectangle.javapublicclassRectangleextendsShape{publicRectangle(){type="Rectangle";}@Overridepublicvoiddraw(){System.out.println("InsideRectangle::draw()method.");}}
Square.javapublicclassSquareextendsShape{publicSquare(){type="Square";}@Overridepublicvoiddraw(){System.out.println("InsideSquare::draw()method.");}}
Circle.javapublicclassCircleextendsShape{publicCircle(){type="Circle";}@Overridepublicvoiddraw(){System.out.println("InsideCircle::draw()method.");}}
Step3CreateaclasstogetconcreateclassesfromdatabaseandstoretheminaHashtable.ShapeCache.javaimportjava.util.Hashtable;publicclassShapeCache{privatestaticHashtableshapeMap=newHashtable();publicstaticShapegetShape(StringshapeId){ShapecachedShape=shapeMap.get(shapeId);
return(Shape)cachedShape.clone();}//foreachshaperundatabasequeryandcreateshape//shapeMap.put(shapeKey,shape);//forexample,weareaddingthreeshapespublicstaticvoidloadCache(){Circlecircle=newCircle();circle.setId("1");shapeMap.put(circle.getId(),circle);Squaresquare=newSquare();square.setId("2");shapeMap.put(square.getId(),square);Rectanglerectangle=newRectangle();rectangle.setId("3");shapeMap.put(rectangle.getId(),rectangle);}}
Step4PrototypePatternDemousesShapeCacheclasstogetclonesofshapesstoredinaHashtable.PrototypePatternDemo.javapublicclassPrototypePatternDemo{publicstaticvoidmain(String[]args){ShapeCache.loadCache();ShapeclonedShape=(Shape)ShapeCache.getShape("1");System.out.println("Shape:"+clonedShape.getType());
ShapeclonedShape2=(Shape)ShapeCache.getShape("2");System.out.println("Shape:"+clonedShape2.getType()); ShapeclonedShape3=(Shape)ShapeCache.getShape("3");System.out.println("Shape:"+clonedShape3.getType()); }}
Step5Verifytheoutput.Shape:CircleShape:SquareShape:Rectangle
ADAPTERPATTERNAdapterpatternworksasabridgebetweentwoincompatibleinterfaces.Thistypeofdesignpatterncomesunderstructuralpatternasthispatterncombinesthecapabilityoftwoindependentinterfaces.Thispatterninvolvesasingleclasswhichisresponsibletojoinfunctionalitiesofindependentorincompatibleinterfaces.Areallifeexamplecouldbeacaseofcardreaderwhichactsasanadapterbetweenmemorycardandalaptop.Youpluginsthememorycardintocardreaderandcardreaderintothelaptopsothatmemorycardcanbereadvialaptop.WearedemonstratinguseofAdapterpatternviafollowingexampleinwhichanaudioplayerdevicecanplaymp3filesonlyandwantstouseanadvancedaudioplayercapableofplayingvlcandmp4files.
ImplementationWe'veaninterfaceMediaPlayerinterfaceandaconcreteclassAudioPlayerimplementingtheMediaPlayerinterface.AudioPlayercanplaymp3formataudiofilesbydefault.We'rehavinganotherinterfaceAdvancedMediaPlayerandconcreteclassesimplementingtheAdvancedMediaPlayerinterface.Theseclassescanplayvlcandmp4formatfiles.WewanttomakeAudioPlayertoplayotherformatsaswell.Toattainthis,we'vecreatedanadapterclassMediaAdapterwhichimplementstheMediaPlayerinterfaceandusesAdvancedMediaPlayerobjectstoplaytherequiredformat.AudioPlayerusestheadapterclassMediaAdapterpassingitthedesiredaudiotypewithoutknowingtheactualclasswhichcanplaythedesiredformat.AdapterPatternDemo,ourdemoclasswilluseAudioPlayerclasstoplayvariousformats.
Step1CreateinterfacesforMediaPlayerandAdvancedMediaPlayer.MediaPlayer.javapublicinterfaceMediaPlayer{publicvoidplay(StringaudioType,StringfileName);}
AdvancedMediaPlayer.javapublicinterfaceAdvancedMediaPlayer{publicvoidplayVlc(StringfileName);publicvoidplayMp4(StringfileName);}
Step2CreateconcreteclassesimplementingtheAdvancedMediaPlayerinterface.VlcPlayer.javapublicclassVlcPlayerimplementsAdvancedMediaPlayer{@OverridepublicvoidplayVlc(StringfileName){System.out.println("Playingvlcfile.Name:"+fileName);}@OverridepublicvoidplayMp4(StringfileName){//donothing}}
Mp4Player.javapublicclassMp4PlayerimplementsAdvancedMediaPlayer{@OverridepublicvoidplayVlc(StringfileName){//donothing}@OverridepublicvoidplayMp4(StringfileName){System.out.println("Playingmp4file.Name:"+fileName);}}
Step3CreateadapterclassimplementingtheMediaPlayerinterface.MediaAdapter.javapublicclassMediaAdapterimplementsMediaPlayer{AdvancedMediaPlayeradvancedMusicPlayer;
publicMediaAdapter(StringaudioType){if(audioType.equalsIgnoreCase("vlc")){advancedMusicPlayer=newVlcPlayer();}elseif(audioType.equalsIgnoreCase("mp4")){advancedMusicPlayer=newMp4Player();}}
@Overridepublicvoidplay(StringaudioType,StringfileName){if(audioType.equalsIgnoreCase("vlc")){advancedMusicPlayer.playVlc(fileName);}elseif(audioType.equalsIgnoreCase("mp4")){advancedMusicPlayer.playMp4(fileName);}}}
Step4CreateconcreteclassimplementingtheMediaPlayerinterface.AudioPlayer.javapublicclassAudioPlayerimplementsMediaPlayer{MediaAdaptermediaAdapter;@Overridepublicvoidplay(StringaudioType,StringfileName){
//inbuiltsupporttoplaymp3musicfilesif(audioType.equalsIgnoreCase("mp3")){System.out.println("Playingmp3file.Name:"+fileName);}//mediaAdapterisprovidingsupporttoplayotherfileformatselseif(audioType.equalsIgnoreCase("vlc")||audioType.equalsIgnoreCase("mp4")){mediaAdapter=newMediaAdapter(audioType);mediaAdapter.play(audioType,fileName);}else{System.out.println("Invalidmedia."+audioType+"formatnotsupported");}}}
Step5UsetheAudioPlayertoplaydifferenttypesofaudioformats.AdapterPatternDemo.javapublicclassAdapterPatternDemo{publicstaticvoidmain(String[]args){AudioPlayeraudioPlayer=newAudioPlayer();audioPlayer.play("mp3","beyondthehorizon.mp3");audioPlayer.play("mp4","alone.mp4");audioPlayer.play("vlc","farfaraway.vlc");audioPlayer.play("avi","mindme.avi");}}
Step6Verifytheoutput.Playingmp3file.Name:beyondthehorizon.mp3Playingmp4file.Name:alone.mp4Playingvlcfile.Name:farfaraway.vlcInvalidmedia.aviformatnotsupported
BRIDGEPATTERNBridgeisusedwhereweneedtodecoupleanabstractionfromitsimplementationsothatthetwocanvaryindependently.Thistypeofdesignpatterncomesunderstructuralpatternasthispatterndecouplesimplementationclassandabstractclassbyprovidingabridgestructurebetweenthem.Thispatterninvolvesaninterfacewhichactsasabridgewhichmakesthefunctionalityofconcreteclassesindependentfrominterfaceimplementerclasses.Bothtypesofclassescanbealteredstructurallywithoutaffectingeachother.WearedemonstratinguseofBridgepatternviafollowingexampleinwhichacirclecanbedrawnindifferentcolorsusingsameabstractclassmethodbutdifferentbridgeimplementerclasses.
ImplementationWe'veaninterfaceDrawAPIinterfacewhichisactingasabridgeimplementerandconcreteclassesRedCircle,GreenCircleimplementingtheDrawAPIinterface.ShapeisanabstractclassandwilluseobjectofDrawAPI.BridgePatternDemo,ourdemoclasswilluseShapeclasstodrawdifferentcoloredcircle.
Step1Createbridgeimplementerinterface.DrawAPI.javapublicinterfaceDrawAPI{publicvoiddrawCircle(intradius,intx,inty);}
Step2CreateconcretebridgeimplementerclassesimplementingtheDrawAPIinterface.RedCircle.javapublicclassRedCircleimplementsDrawAPI{@OverridepublicvoiddrawCircle(intradius,intx,inty){System.out.println("DrawingCircle[color:red,radius:"+radius+",x:"+x+","+y+"]");}}
GreenCircle.javapublicclassGreenCircleimplementsDrawAPI{@OverridepublicvoiddrawCircle(intradius,intx,inty){System.out.println("DrawingCircle[color:green,radius:"+radius+",x:"+x+","+y+"]");}}
Step3CreateanabstractclassShapeusingtheDrawAPIinterface.Shape.javapublicabstractclassShape{protectedDrawAPIdrawAPI;protectedShape(DrawAPIdrawAPI){this.drawAPI=drawAPI;}publicabstractvoiddraw();}
Step4CreateconcreteclassimplementingtheShapeinterface.Circle.javapublicclassCircleextendsShape{privateintx,y,radius;publicCircle(intx,inty,intradius,DrawAPIdrawAPI){
super(drawAPI);this.x=x;this.y=y;this.radius=radius;}publicvoiddraw(){drawAPI.drawCircle(radius,x,y);}}
Step5UsetheShapeandDrawAPIclassestodrawdifferentcoloredcircles.BridgePatternDemo.javapublicclassBridgePatternDemo{publicstaticvoidmain(String[]args){ShaperedCircle=newCircle(100,100,10,newRedCircle());ShapegreenCircle=newCircle(100,100,10,newGreenCircle());redCircle.draw();greenCircle.draw();}}
Step6Verifytheoutput.DrawingCircle[color:red,radius:10,x:100,100]DrawingCircle[color:green,radius:10,x:100,100]
FILTER/CRITERIAPATTERNFilterpatternorCriteriapatternisadesignpatternthatenablesdeveloperstofilterasetofobjects,usingdifferentcriteria,chainingtheminadecoupledwaythroughlogicaloperations.Thistypeofdesignpatterncomesunderstructuralpatternasthispatterniscombiningmultiplecriteriatoobtainsinglecriteria.
ImplementationWe'regoingtocreateaPersonobject,CriteriainterfaceandconcreteclassesimplementingthisinterfacetofilterlistofPersonobjects.CriteriaPatternDemo,ourdemoclassusesCriteriaobjectstofilterListofPersonobjectsbasedonvariouscriteriaandtheircombinations.
Step1Createaclassonwhichcriteriaistobeapplied.Person.javapublicclassPerson{privateStringname;privateStringgender;privateStringmaritalStatus;
publicPerson(Stringname,Stringgender,StringmaritalStatus){this.name=name;this.gender=gender;this.maritalStatus=maritalStatus;}publicStringgetName(){returnname;}publicStringgetGender(){returngender;}publicStringgetMaritalStatus(){returnmaritalStatus;}}
Step2CreateaninterfaceforCriteria.Criteria.javaimportjava.util.List;publicinterfaceCriteria{publicListmeetCriteria(Listpersons);}
Step3CreateconcreteclassesimplementingtheCriteriainterface.CriteriaMale.javaimportjava.util.ArrayList;importjava.util.List;publicclassCriteriaMaleimplementsCriteria{@OverridepublicListmeetCriteria(Listpersons){ListmalePersons=newArrayList();for(Personperson:persons){if(person.getGender().equalsIgnoreCase("MALE")){malePersons.add(person);}}returnmalePersons;}}
CriteriaFemale.javaimportjava.util.ArrayList;importjava.util.List;publicclassCriteriaFemaleimplementsCriteria{@OverridepublicListmeetCriteria(Listpersons){ListfemalePersons=newArrayList();for(Personperson:persons){if(person.getGender().equalsIgnoreCase("FEMALE")){femalePersons.add(person);}}returnfemalePersons;}}
CriteriaSingle.javaimportjava.util.ArrayList;importjava.util.List;publicclassCriteriaSingleimplementsCriteria{@OverridepublicListmeetCriteria(Listpersons){ListsinglePersons=newArrayList();for(Personperson:persons){if(person.getMaritalStatus().equalsIgnoreCase("SINGLE")){singlePersons.add(person);}}
returnsinglePersons;}}
AndCriteria.javaimportjava.util.List;publicclassAndCriteriaimplementsCriteria{privateCriteriacriteria;privateCriteriaotherCriteria;publicAndCriteria(Criteriacriteria,CriteriaotherCriteria){this.criteria=criteria;this.otherCriteria=otherCriteria;}@OverridepublicListmeetCriteria(Listpersons){ListfirstCriteriaPersons=criteria.meetCriteria(persons);returnotherCriteria.meetCriteria(firstCriteriaPersons);}}
OrCriteria.javaimportjava.util.List;publicclassAndCriteriaimplementsCriteria{privateCriteriacriteria;privateCriteriaotherCriteria;publicAndCriteria(Criteriacriteria,CriteriaotherCriteria){this.criteria=criteria;this.otherCriteria=otherCriteria;}@OverridepublicListmeetCriteria(Listpersons){ListfirstCriteriaItems=criteria.meetCriteria(persons);ListotherCriteriaItems=otherCriteria.meetCriteria(persons);for(Personperson:otherCriteriaItems){if(!firstCriteriaItems.contains(person)){firstCriteriaItems.add(person);}}returnfirstCriteriaItems;}}
Step4UsedifferentCriteriaandtheircombinationtofilteroutpersons.CriteriaPatternDemo.javapublicclassCriteriaPatternDemo{publicstaticvoidmain(String[]args){Listpersons=newArrayList();persons.add(newPerson("Robert","Male","Single"));persons.add(newPerson("John","Male","Married"));persons.add(newPerson("Laura","Female","Married"));persons.add(newPerson("Diana","Female","Single"));persons.add(newPerson("Mike","Male","Single"));persons.add(newPerson("Bobby","Male","Single"));Criteriamale=newCriteriaMale();Criteriafemale=newCriteriaFemale();Criteriasingle=newCriteriaSingle();CriteriasingleMale=newAndCriteria(single,male);CriteriasingleOrFemale=newOrCriteria(single,female);System.out.println("Males:");printPersons(male.meetCriteria(persons));System.out.println("\nFemales:");printPersons(female.meetCriteria(persons));System.out.println("\nSingleMales:");printPersons(singleMale.meetCriteria(persons));System.out.println("\nSingleOrFemales:");printPersons(singleOrFemale.meetCriteria(persons));
}publicstaticvoidprintPersons(Listpersons){for(Personperson:persons){System.out.println("Person:[Name:"+person.getName()+",Gender:"+person.getGender()+",MaritalStatus:"+person.getMaritalStatus()+"]");}}}
Step5Verifytheoutput.Males:Person:[Name:Robert,Gender:Male,MaritalStatus:Single]Person:[Name:John,Gender:Male,MaritalStatus:Married]Person:[Name:Mike,Gender:Male,MaritalStatus:Single]Person:[Name:Bobby,Gender:Male,MaritalStatus:Single]Females:Person:[Name:Laura,Gender:Female,MaritalStatus:Married]Person:[Name:Diana,Gender:Female,MaritalStatus:Single]SingleMales:Person:[Name:Robert,Gender:Male,MaritalStatus:Single]Person:[Name:Mike,Gender:Male,MaritalStatus:Single]Person:[Name:Bobby,Gender:Male,MaritalStatus:Single]SingleOrFemales:Person:[Name:Robert,Gender:Male,MaritalStatus:Single]Person:[Name:Diana,Gender:Female,MaritalStatus:Single]Person:[Name:Mike,Gender:Male,MaritalStatus:Single]Person:[Name:Bobby,Gender:Male,MaritalStatus:Single]Person:[Name:Laura,Gender:Female,MaritalStatus:Married]
COMPOSITEPATTERNCompositepatternisusedwhereweneedtotreatagroupofobjectsinsimilarwayasasingleobject.Compositepatterncomposesobjectsintermofatreestructuretorepresentpartaswellaswholehierarchy.Thistypeofdesignpatterncomesunderstructuralpatternasthispatterncreatesatreestructureofgroupofobjects.Thispatterncreatesaclasscontainsgroupofitsownobjects.Thisclassprovideswaystomodifyitsgroupofsameobjects.WearedemonstratinguseofCompositepatternviafollowingexampleinwhichshowemployeeshierarchyofanorganization.
ImplementationWe'veaclassEmployeewhichactsascompositepatternactorclass.CompositePatternDemo,ourdemoclasswilluseEmployeeclasstoadddepartmentlevelhierarchyandprintallemployees.
Step1CreateEmployeeclasshavinglistofEmployeeobjects.Employee.java
importjava.util.ArrayList;importjava.util.List;publicclassEmployee{privateStringname;privateStringdept;privateintsalary;privateListsubordinates;//constructorpublicEmployee(Stringname,Stringdept,intsal){this.name=name;this.dept=dept;this.salary=sal;subordinates=newArrayList();}publicvoidadd(Employeee){subordinates.add(e);}publicvoidremove(Employeee){subordinates.remove(e);}publicListgetSubordinates(){returnsubordinates;}publicStringtoString(){return("Employee:[Name:"+name+",dept:"+dept+",salary:"+salary+"]");}}
Step2UsetheEmployeeclasstocreateandprintemployeehierarchy.CompositePatternDemo.javapublicclassCompositePatternDemo{publicstaticvoidmain(String[]args){EmployeeCEO=newEmployee("John","CEO",30000);EmployeeheadSales=newEmployee("Robert","HeadSales",20000);EmployeeheadMarketing=newEmployee("Michel","HeadMarketing",20000);Employeeclerk1=newEmployee("Laura","Marketing",10000);Employeeclerk2=newEmployee("Bob","Marketing",10000);EmployeesalesExecutive1=newEmployee("Richard","Sales",10000);EmployeesalesExecutive2=newEmployee("Rob","Sales",10000);CEO.add(headSales);CEO.add(headMarketing);headSales.add(salesExecutive1);headSales.add(salesExecutive2);headMarketing.add(clerk1);headMarketing.add(clerk2);//printallemployeesoftheorganizationSystem.out.println(CEO);for(EmployeeheadEmployee:CEO.getSubordinates()){System.out.println(headEmployee);for(Employeeemployee:headEmployee.getSubordinates()){System.out.println(employee);}}}}
Step3Verifytheoutput.Employee:[Name:John,dept:CEO,salary:30000]Employee:[Name:Robert,dept:HeadSales,salary:20000]Employee:[Name:Richard,dept:Sales,salary:10000]Employee:[Name:Rob,dept:Sales,salary:10000]Employee:[Name:Michel,dept:HeadMarketing,salary:20000]Employee:[Name:Laura,dept:Marketing,salary:10000]Employee:[Name:Bob,dept:Marketing,salary:10000]
DECORATORPATTERNDecoratorpatternallowstoaddnewfunctionalityanexistingobjectwithoutalteringitsstructure.Thistypeofdesignpatterncomesunderstructuralpatternasthispatternactsasawrappertoexistingclass.Thispatterncreatesadecoratorclasswhichwrapstheoriginalclassandprovidesadditionalfunctionalitykeepingclassmethodssignatureintact.WearedemonstratinguseofDecoratorpatternviafollowingexampleinwhichwe'lldecorateashapewithsomecolorwithoutaltershapeclass.
ImplementationWe'regoingtocreateaShapeinterfaceandconcreteclassesimplementingtheShapeinterface.WethencreateaabstractdecoratorclassShapeDecoratorimplementingtheShapeinterfaceandhavingShapeobjectasitsinstancevariable.RedShapeDecoratorisconcreteclassimplementingShapeDecorator.DecoratorPatternDemo,ourdemoclasswilluseRedShapeDecoratortodecorateShapeobjects.
Step1Createaninterface.Shape.javapublicinterfaceShape{voiddraw();}
Step2Createconcreteclassesimplementingthesameinterface.Rectangle.javapublicclassRectangleimplementsShape{@Overridepublicvoiddraw(){System.out.println("Shape:Rectangle");}}
Circle.javapublicclassCircleimplementsShape{@Overridepublicvoiddraw(){System.out.println("Shape:Circle");}}
Step3CreateabstractdecoratorclassimplementingtheShapeinterface.ShapeDecorator.java
publicabstractclassShapeDecoratorimplementsShape{protectedShapedecoratedShape;publicShapeDecorator(ShapedecoratedShape){this.decoratedShape=decoratedShape;}publicvoiddraw(){decoratedShape.draw();}}
Step4CreateconcretedecoratorclassextendingtheShapeDecoratorclass.RedShapeDecorator.javapublicclassRedShapeDecoratorextendsShapeDecorator{publicRedShapeDecorator(ShapedecoratedShape){super(decoratedShape);}@Overridepublicvoiddraw(){decoratedShape.draw();setRedBorder(decoratedShape);}privatevoidsetRedBorder(ShapedecoratedShape){System.out.println("BorderColor:Red");}}
Step5UsetheRedShapeDecoratortodecorateShapeobjects.DecoratorPatternDemo.javapublicclassDecoratorPatternDemo{publicstaticvoidmain(String[]args){Shapecircle=newCircle();ShaperedCircle=newRedShapeDecorator(newCircle());ShaperedRectangle=newRedShapeDecorator(newRectangle());System.out.println("Circlewithnormalborder");circle.draw();System.out.println("\nCircleofredborder");redCircle.draw();System.out.println("\nRectangleofredborder");redRectangle.draw();}}
Step6Verifytheoutput.CirclewithnormalborderShape:CircleCircleofredborderShape:CircleBorderColor:RedRectangleofredborderShape:RectangleBorderColor:Red
FACADEPATTERNFacadepatternhidesthecomplexitiesofthesystemandprovidesaninterfacetotheclientusingwhichtheclientcanaccessthesystem.Thistypeofdesignpatterncomesunderstructuralpatternasthispatternaddsaninterfacetoexitingsystemtohideitscomplexities.Thispatterninvolvesasingleclasswhichprovidessimplifiedmethodswhicharerequiredbyclientanddelegatescallstoexistingsystemclassesmethods.
Implementation
We'regoingtocreateaShapeinterfaceandconcreteclassesimplementingtheShapeinterface.AfacadeclassShapeMakerisdefinedasanextstep.ShapeMakerclassusestheconcreteclassestodelegatesusercallstotheseclasses.FacadePatternDemo,ourdemoclasswilluseShapeMakerclasstoshowtheresults.
Step1Createaninterface.Shape.javapublicinterfaceShape{voiddraw();}
Step2Createconcreteclassesimplementingthesameinterface.Rectangle.javapublicclassRectangleimplementsShape{@Overridepublicvoiddraw(){System.out.println("Rectangle::draw()");}}
Square.javapublicclassSquareimplementsShape{@Overridepublicvoiddraw(){System.out.println("Square::draw()");}}
Circle.javapublicclassCircleimplementsShape{@Overridepublicvoiddraw(){System.out.println("Circle::draw()");}}
Step3Createafacadeclass.ShapeMaker.javapublicclassShapeMaker{privateShapecircle;privateShaperectangle;privateShapesquare;publicShapeMaker(){circle=newCircle();rectangle=newRectangle();
square=newSquare();}publicvoiddrawCircle(){circle.draw();}publicvoiddrawRectangle(){rectangle.draw();}publicvoiddrawSquare(){square.draw();}}
Step4Usethefacadetodrawvarioustypesofshapes.FacadePatternDemo.javapublicclassFacadePatternDemo{publicstaticvoidmain(String[]args){ShapeMakershapeMaker=newShapeMaker();shapeMaker.drawCircle();shapeMaker.drawRectangle();shapeMaker.drawSquare(); }}
Step5Verifytheoutput.Circle::draw()Rectangle::draw()Square::draw()
FLYWEIGHTPATTERNFlyweightpatternisprimarilyusedtoreducethenumberofobjectscreated,todecreasememoryfootprintandincreaseperformance.Thistypeofdesignpatterncomesunderstructuralpatternasthispatternprovideswaystodecreaseobjectscountthusimprovingapplicationrequiredobjectsstructure.Flyweightpatterntrytoreusealreadyexistingsimilarkindobjectsbystoringthemandcreatesnewobjectwhennomatchingobjectisfound.We'lldemonstratethispatternbydrawing20circleofdifferentlocationsbutwe'llcreatingonly5objects.Only5colorsareavailablesocolorpropertyisusedtocheckalreadyexistingCircleobjects.
ImplementationWe'regoingtocreateaShapeinterfaceandconcreteclassCircleimplementingtheShapeinterface.AfactoryclassShapeFactoryisdefinedasanextstep.ShapeFactoryhaveaHashMapofCirclehavingkeyascoloroftheCircleobject.WheneverarequestcomestocreateacircleofparticularcolortoShapeFactory.ShapeFactorychecksthecircleobjectinitsHashMap,ifobjectofCirclefound,thatobjectisreturnedotherwiseanewobjectiscreated,storedinhashmapforfutureuseandreturnedtoclient.FlyWeightPatternDemo,ourdemoclasswilluseShapeFactorytogetaShapeobject.Itwillpassinformation(red/green/blue/black/white)toShapeFactorytogetthecircleofdesiredcoloritneeds.
Step1
Createaninterface.Shape.javapublicinterfaceShape{voiddraw();}
Step2Createconcreteclassimplementingthesameinterface.Circle.javapublicclassCircleimplementsShape{privateStringcolor;privateintx;privateinty;privateintradius;publicCircle(Stringcolor){this.color=color;}publicvoidsetX(intx){this.x=x;}publicvoidsetY(inty){this.y=y;}publicvoidsetRadius(intradius){this.radius=radius;}@Overridepublicvoiddraw(){System.out.println("Circle:Draw()[Color:"+color+",x:"+x+",y:"+y+",radius:"+radius);}}
Step3CreateaFactorytogenerateobjectofconcreteclassbasedongiveninformation.ShapeFactory.javaimportjava.util.HashMap;publicclassShapeFactory{privatestaticfinalHashMapcircleMap=newHashMap();publicstaticShapegetCircle(Stringcolor){Circlecircle=(Circle)circleMap.get(color);if(circle==null){circle=newCircle(color);circleMap.put(color,circle);System.out.println("Creatingcircleofcolor:"+color);}returncircle;}}
Step4UsetheFactorytogetobjectofconcreteclassbypassinganinformationsuchascolor.FlyweightPatternDemo.javapublicclassFlyweightPatternDemo{privatestaticfinalStringcolors[]={"Red","Green","Blue","White","Black"};publicstaticvoidmain(String[]args){for(inti=0;i