design pattern quick guides

65
http://www.tutorialspoint.com/design_pattern/design_pattern_quick_guide.htm Copyright © tutorialspoint.com DESIGN PATTERN QUICK GUIDE Design patterns represent the best practices used by experienced objectoriented software developers. Design patterns are solutions to general problems that software developers faced during software development. These solutions were obtained by trial and error by numerous software developers over quite a substantial period of time. What is Gang of Four ? In 1994, four authors Erich Gamma, Richard Helm, Ralph Johnson und John Vlissides published a book titled Design Patterns Elements of Reusable ObjectOriented Software which initiated the concept of Design Pattern in Software development. These authors are collectively known as Gang of Four . According to these authors design patterns are primarily based on the following principles of object orientated design. Program to an interface not an implementation Favor object composition over inheritance Usage of Design Pattern Design Patterns have two main usages in software development. Common platform for developers Design patterns provide a standard terminology and are specific to particular scenario. For example, a singleton design pattern signifies use of single object so all developers familiar with single design pattern will make use of single object and they can tell each other that program is following a singleton pattern. Best Practices Design patterns have been evolved over a long period of time and they provide best solutions to certain problems faced during software development. Learning these patterns helps unexperienced developers to learn software design in an easy and faster way. Types of Design Pattern As per the design pattern reference book Design Patterns Elements of Reusable ObjectOriented Software , there are 23 design patterns. These patterns can be classified in three categories: Creational, Structural and behavioral patterns. We'll also discuss another category of design patterns: J2EE design patterns. S.N. Pattern & Description 1 Creational Patterns These design patterns provides way to create objects while hiding the creation logic, rather than instantiating objects directly using new opreator. This gives program more flexibility in deciding which objects need to be created for a given use case. 2 Structural Patterns These design patterns concern class and object composition. Concept of inheritance is used to compose interfaces and define ways to compose objects to obtain new functionalities. 3 Behavioral Patterns These design patterns are specifically concerned with communication between objects. 4 J2EE Patterns These design patterns are specifically concerned with the presentation tier. These patterns are identified by Sun Java Center. FACTORY PATTERN Factory pattern is one of most used design pattern in Java. This type of design pattern comes under creational pattern as this pattern provides one of the best ways to create an object. In Factory pattern, we create object without exposing the creation logic to the client and refer to newly created object using a common interface. Implementation We're going to create a Shape interface and concrete classes implementing the Shape interface. A factory class ShapeFactory is defined as a next step. FactoryPatternDemo, our demo class will use ShapeFactory to get a Shape object. It will pass information (CIRCLE / RECTANGLE / SQUARE) to ShapeFactory to get the type of object it needs.

Upload: tran-ky-phan

Post on 18-Aug-2015

219 views

Category:

Documents


2 download

DESCRIPTION

Guide to learn Design pattern

TRANSCRIPT

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