Design Pattern Quick Guides
Design Pattern Quick Guides
http://www.tutorialspoint.com/design_pattern/design_pattern_quick_guide.htm
Copyrighttutorialspoint.com
Designpatternsrepresentthebestpracticesusedbyexperiencedobjectorientedsoftwaredevelopers.Designpatternsaresolutionstogeneral
problemsthatsoftwaredevelopersfacedduringsoftwaredevelopment.Thesesolutionswereobtainedbytrialanderrorbynumeroussoftware
developersoverquiteasubstantialperiodoftime.
WhatisGangofFourGOF ?
In1994,fourauthorsErichGamma,RichardHelm,RalphJohnsonundJohnVlissidespublishedabooktitledDesignPatternsElements
ofReusableObjectOrientedSoftwarewhichinitiatedtheconceptofDesignPatterninSoftwaredevelopment.
TheseauthorsarecollectivelyknownasGangofFour GOF .Accordingtotheseauthorsdesignpatternsareprimarilybasedonthefollowing
principlesofobjectorientateddesign.
Programtoaninterfacenotanimplementation
Favorobjectcompositionoverinheritance
UsageofDesignPattern
DesignPatternshavetwomainusagesinsoftwaredevelopment.
Commonplatformfordevelopers
Designpatternsprovideastandardterminologyandarespecifictoparticularscenario.Forexample,asingletondesignpatternsignifiesuseof
singleobjectsoalldevelopersfamiliarwithsingledesignpatternwillmakeuseofsingleobjectandtheycantelleachotherthatprogramis
followingasingletonpattern.
BestPractices
Designpatternshavebeenevolvedoveralongperiodoftimeandtheyprovidebestsolutionstocertainproblemsfacedduringsoftware
development.Learningthesepatternshelpsunexperienceddeveloperstolearnsoftwaredesigninaneasyandfasterway.
TypesofDesignPattern
AsperthedesignpatternreferencebookDesignPatternsElementsofReusableObjectOrientedSoftware,thereare23design
patterns.Thesepatternscanbeclassifiedinthreecategories:Creational,Structuralandbehavioralpatterns.We'llalsodiscussanothercategory
ofdesignpatterns:J2EEdesignpatterns.
S.N.
Pattern&Description
CreationalPatterns
Thesedesignpatternsprovideswaytocreateobjectswhilehidingthecreationlogic,ratherthaninstantiatingobjectsdirectlyusing
newopreator.Thisgivesprogrammoreflexibilityindecidingwhichobjectsneedtobecreatedforagivenusecase.
StructuralPatterns
Thesedesignpatternsconcernclassandobjectcomposition.Conceptofinheritanceisusedtocomposeinterfacesanddefinewaysto
composeobjectstoobtainnewfunctionalities.
BehavioralPatterns
Thesedesignpatternsarespecificallyconcernedwithcommunicationbetweenobjects.
J2EEPatterns
Thesedesignpatternsarespecificallyconcernedwiththepresentationtier.ThesepatternsareidentifiedbySunJavaCenter.
FACTORYPATTERN
FactorypatternisoneofmostuseddesignpatterninJava.Thistypeofdesignpatterncomesundercreationalpatternasthispatternprovides
oneofthebestwaystocreateanobject.
InFactorypattern,wecreateobjectwithoutexposingthecreationlogictotheclientandrefertonewlycreatedobjectusingacommoninterface.
Implementation
We'regoingtocreateaShapeinterfaceandconcreteclassesimplementingtheShapeinterface.AfactoryclassShapeFactoryisdefinedasa
nextstep.
FactoryPatternDemo,ourdemoclasswilluseShapeFactorytogetaShapeobject.Itwillpassinformation(CIRCLE/RECTANGLE/SQUARE)
toShapeFactorytogetthetypeofobjectitneeds.
Step1
Createaninterface.
Shape.java
publicinterfaceShape{
voiddraw();
}
Step2
Createconcreteclassesimplementingthesameinterface.
Rectangle.java
publicclassRectangleimplementsShape{
@Override
publicvoiddraw(){
System.out.println("InsideRectangle::draw()method.");
}
}
Square.java
publicclassSquareimplementsShape{
@Override
publicvoiddraw(){
System.out.println("InsideSquare::draw()method.");
}
}
Circle.java
publicclassCircleimplementsShape{
@Override
publicvoiddraw(){
System.out.println("InsideCircle::draw()method.");
}
}
Step3
CreateaFactorytogenerateobjectofconcreteclassbasedongiveninformation.
ShapeFactory.java
publicclassShapeFactory{
//usegetShapemethodtogetobjectoftypeshape
publicShapegetShape(StringshapeType){
if(shapeType==null){
returnnull;
}
if(shapeType.equalsIgnoreCase("CIRCLE")){
returnnewCircle();
}elseif(shapeType.equalsIgnoreCase("RECTANGLE")){
returnnewRectangle();
}elseif(shapeType.equalsIgnoreCase("SQUARE")){
returnnewSquare();
}
returnnull;
}
}
Step4
UsetheFactorytogetobjectofconcreteclassbypassinganinformationsuchastype.
FactoryPatternDemo.java
publicclassFactoryPatternDemo{
publicstaticvoidmain(String[]args){
ShapeFactoryshapeFactory=newShapeFactory();
//getanobjectofCircleandcallitsdrawmethod.
Shapeshape1=shapeFactory.getShape("CIRCLE");
//calldrawmethodofCircle
shape1.draw();
//getanobjectofRectangleandcallitsdrawmethod.
Shapeshape2=shapeFactory.getShape("RECTANGLE");
//calldrawmethodofRectangle
shape2.draw();
//getanobjectofSquareandcallitsdrawmethod.
Shapeshape3=shapeFactory.getShape("SQUARE");
//calldrawmethodofcircle
shape3.draw();
}
}
Step5
Verifytheoutput.
InsideCircle::draw()method.
InsideRectangle::draw()method.
InsideSquare::draw()method.
ABSTRACTFACTORYPATTERN
AbstractFactorypatternsworksaroundasuperfactorywhichcreatesotherfactories.ThisfactoryisalsocalledasFactoryoffactories.This
typeofdesignpatterncomesundercreationalpatternasthispatternprovidesoneofthebestwaystocreateanobject.
InAbstractFactorypatternaninterfaceisresponsibleforcreatingafactoryofrelatedobjects,withoutexplicitlyspecifyingtheirclasses.Each
generatedfactorycangivetheobjectsaspertheFactorypattern.
Implementation
We'regoingtocreateaShapeandColorinterfacesandconcreteclassesimplementingtheseinterfaces.Wecreatesanabstractfactoryclass
AbstractFactoryasnextstep.FactoryclassesShapeFactoryandColorFactoryaredefinedwhereeachfactoryextendsAbstractFactory.A
factorycreator/generatorclassFactoryProduceriscreated.
AbstractFactoryPatternDemo,ourdemoclassusesFactoryProducertogetaAbstractFactoryobject.Itwillpassinformation(CIRCLE/
RECTANGLE/SQUAREforShape)toAbstractFactorytogetthetypeofobjectitneeds.Italsopassesinformation(RED/GREEN/BLUEfor
Color)toAbstractFactorytogetthetypeofobjectitneeds.
Step1
CreateaninterfaceforShapes.
Shape.java
publicinterfaceShape{
voiddraw();
}
Step2
Createconcreteclassesimplementingthesameinterface.
Rectangle.java
publicclassRectangleimplementsShape{
@Override
publicvoiddraw(){
System.out.println("InsideRectangle::draw()method.");
}
}
Square.java
publicclassSquareimplementsShape{
@Override
publicvoiddraw(){
System.out.println("InsideSquare::draw()method.");
}
}
Circle.java
publicclassCircleimplementsShape{
@Override
publicvoiddraw(){
System.out.println("InsideCircle::draw()method.");
}
}
Step3
CreateaninterfaceforColors.
Color.java
publicinterfaceColor{
voidfill();
}
Step4
Createconcreteclassesimplementingthesameinterface.
Red.java
publicclassRedimplementsColor{
@Override
publicvoidfill(){
System.out.println("InsideRed::fill()method.");
}
}
Green.java
publicclassGreenimplementsColor{
@Override
publicvoidfill(){
System.out.println("InsideGreen::fill()method.");
}
}
Blue.java
publicclassBlueimplementsColor{
@Override
publicvoidfill(){
System.out.println("InsideBlue::fill()method.");
}
}
Step5
CreateanAbstractclasstogetfactoriesforColorandShapeObjects.
AbstractFactory.java
publicabstractclassAbstractFactory{
abstractColorgetColor(Stringcolor);
abstractShapegetShape(Stringshape);
}
Step6
CreateFactoryclassesextendingAbstractFactorytogenerateobjectofconcreteclassbasedongiveninformation.
ShapeFactory.java
publicclassShapeFactoryextendsAbstractFactory{
@Override
publicShapegetShape(StringshapeType){
if(shapeType==null){
returnnull;
}
if(shapeType.equalsIgnoreCase("CIRCLE")){
returnnewCircle();
}elseif(shapeType.equalsIgnoreCase("RECTANGLE")){
returnnewRectangle();
}elseif(shapeType.equalsIgnoreCase("SQUARE")){
returnnewSquare();
}
returnnull;
}
@Override
ColorgetColor(Stringcolor){
returnnull;
}
}
ColorFactory.java
publicclassColorFactoryextendsAbstractFactory{
@Override
publicShapegetShape(StringshapeType){
returnnull;
}
@Override
ColorgetColor(Stringcolor){
if(color==null){
returnnull;
}
if(color.equalsIgnoreCase("RED")){
returnnewRed();
}elseif(color.equalsIgnoreCase("GREEN")){
returnnewGreen();
}elseif(color.equalsIgnoreCase("BLUE")){
returnnewBlue();
}
returnnull;
}
}
Step7
CreateaFactorygenerator/producerclasstogetfactoriesbypassinganinformationsuchasShapeorColor
FactoryProducer.java
publicclassFactoryProducer{
publicstaticAbstractFactorygetFactory(Stringchoice){
if(choice.equalsIgnoreCase("SHAPE")){
returnnewShapeFactory();
}elseif(choice.equalsIgnoreCase("COLOR")){
returnnewColorFactory();
}
returnnull;
}
}
Step8
UsetheFactoryProducertogetAbstractFactoryinordertogetfactoriesofconcreteclassesbypassinganinformationsuchastype.
AbstractFactoryPatternDemo.java
publicclassAbstractFactoryPatternDemo{
publicstaticvoidmain(String[]args){
//getshapefactory
AbstractFactoryshapeFactory=FactoryProducer.getFactory("SHAPE");
//getanobjectofShapeCircle
Shapeshape1=shapeFactory.getShape("CIRCLE");
//calldrawmethodofShapeCircle
shape1.draw();
//getanobjectofShapeRectangle
Shapeshape2=shapeFactory.getShape("RECTANGLE");
//calldrawmethodofShapeRectangle
shape2.draw();
//getanobjectofShapeSquare
Shapeshape3=shapeFactory.getShape("SQUARE");
//calldrawmethodofShapeSquare
shape3.draw();
//getcolorfactory
AbstractFactorycolorFactory=FactoryProducer.getFactory("COLOR");
//getanobjectofColorRed
Colorcolor1=colorFactory.getColor("RED");
//callfillmethodofRed
color1.fill();
//getanobjectofColorGreen
Colorcolor2=colorFactory.getColor("Green");
//callfillmethodofGreen
color2.fill();
//getanobjectofColorBlue
Colorcolor3=colorFactory.getColor("BLUE");
//callfillmethodofColorBlue
color3.fill();
}
}
Step9
Verifytheoutput.
InsideCircle::draw()method.
InsideRectangle::draw()method.
InsideSquare::draw()method.
InsideRed::fill()method.
InsideGreen::fill()method.
InsideBlue::fill()method.
SINGLETONPATTERN
SingletonpatternisoneofthesimplestdesignpatternsinJava.Thistypeofdesignpatterncomesundercreationalpatternasthispattern
providesoneofthebestwaytocreateanobject.
Thispatterninvolvesasingleclasswhichisresponsibletocreatesownobjectwhilemakingsurethatonlysingleobjectgetcreated.Thisclass
providesawaytoaccessitsonlyobjectwhichcanbeaccesseddirectlywithoutneedtoinstantiatetheobjectoftheclass.
Implementation
We'regoingtocreateaSingleObjectclass.SingleObjectclasshaveitsconstructorasprivateandhaveastaticinstanceofitself.
SingleObjectclassprovidesastaticmethodtogetitsstaticinstancetooutsideworld.SingletonPatternDemo,ourdemoclasswilluse
SingleObjectclasstogetaSingleObjectobject.
Step1
CreateaSingletonClass.
SingleObject.java
publicclassSingleObject{
//createanobjectofSingleObject
privatestaticSingleObjectinstance=newSingleObject();
//maketheconstructorprivatesothatthisclasscannotbe
//instantiated
privateSingleObject(){}
//Gettheonlyobjectavailable
publicstaticSingleObjectgetInstance(){
returninstance;
}
publicvoidshowMessage(){
System.out.println("HelloWorld!");
}
}
Step2
Gettheonlyobjectfromthesingletonclass.
SingletonPatternDemo.java
publicclassSingletonPatternDemo{
publicstaticvoidmain(String[]args){
//illegalconstruct
//CompileTimeError:TheconstructorSingleObject()isnotvisible
//SingleObjectobject=newSingleObject();
//Gettheonlyobjectavailable
SingleObjectobject=SingleObject.getInstance();
//showthemessage
object.showMessage();
}
}
Step3
Verifytheoutput.
HelloWorld!
BUILDERPATTERN
Builderpatternbuildsacomplexobjectusingsimpleobjectsandusingastepbystepapproach.Thistypeofdesignpatterncomesunder
creationalpatternasthispatternprovidesoneofthebestwaystocreateanobject.
ABuilderclassbuildsthefinalobjectstepbystep.Thisbuilderisindependentofotherobjects.
Implementation
We'veconsideredabusinesscaseoffastfoodrestaurantwhereatypicalmealcouldbeaburgerandacolddrink.BurgercouldbeeitheraVeg
BurgerorChickenBurgerandwillbepackedbyawrapper.Colddrinkcouldbeeitheracokeorpepsiandwillbepackedinabottle.
We'regoingtocreateanIteminterfacerepresentingfooditemssuchasburgersandcolddrinksandconcreteclassesimplementingtheItem
interfaceandaPackinginterfacerepresentingpackagingoffooditemsandconcreteclassesimplementingthePackinginterfaceasburger
wouldbepackedinwrapperandcolddrinkwouldbepackedasbottle.
WethencreateaMealclasshavingArrayListofItemandaMealBuildertobuilddifferenttypesofMealobjectbycombiningItem.
BuilderPatternDemo,ourdemoclasswilluseMealBuildertobuildaMeal.
Step1
CreateaninterfaceItemrepresentingfooditemandpacking.
Item.java
publicinterfaceItem{
publicStringname();
publicPackingpacking();
publicfloatprice();
}
Packing.java
publicinterfacePacking{
publicStringpack();
}
Step2
CreateconcreateclassesimplementingthePackinginterface.
Wrapper.java
publicclassWrapperimplementsPacking{
@Override
publicStringpack(){
return"Wrapper";
}
}
Bottle.java
publicclassBottleimplementsPacking{
@Override
publicStringpack(){
return"Bottle";
}
}
Step3
Createabstractclassesimplementingtheiteminterfaceprovidingdefaultfunctionalities.
Burger.java
publicabstractclassBurgerimplementsItem{
@Override
publicPackingpacking(){
returnnewWrapper();
}
@Override
publicabstractfloatprice();
}
ColdDrink.java
publicabstractclassColdDrinkimplementsItem{
@Override
publicPackingpacking(){
returnnewBottle();
@Override
publicabstractfloatprice();
Step4
CreateconcreteclassesextendingBurgerandColdDrinkclasses
VegBurger.java
publicclassVegBurgerextendsBurger{
@Override
publicfloatprice(){
return25.0f;
}
@Override
publicStringname(){
return"VegBurger";
}
}
ChickenBurger.java
publicclassChickenBurgerextendsBurger{
@Override
publicfloatprice(){
return50.5f;
}
@Override
publicStringname(){
return"ChickenBurger";
}
}
Coke.java
publicclassCokeextendsColdDrink{
@Override
publicfloatprice(){
return30.0f;
}
@Override
publicStringname(){
return"Coke";
}
}
Pepsi.java
publicclassPepsiextendsColdDrink{
@Override
publicfloatprice(){
return35.0f;
}
@Override
publicStringname(){
return"Pepsi";
}
}
Step5
CreateaMealclasshavingItemobjectsdefinedabove.
Meal.java
importjava.util.ArrayList;
importjava.util.List;
publicclassMeal{
privateList<Item>items=newArrayList<Item>();
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());
}
}
}
Step6
CreateaMealBuilderclass,theactualbuilderclassresponsibletocreateMealobjects.
MealBuilder.java
publicclassMealBuilder{
publicMealprepareVegMeal(){
Mealmeal=newMeal();
meal.addItem(newVegBurger());
meal.addItem(newCoke());
returnmeal;
}
publicMealprepareNonVegMeal(){
Mealmeal=newMeal();
meal.addItem(newChickenBurger());
meal.addItem(newPepsi());
returnmeal;
}
}
Step7
BuiderPatternDemousesMealBuidertodemonstratebuilderpattern.
BuilderPatternDemo.java
publicclassBuilderPatternDemo{
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());
}
}
Step8
Verifytheoutput.
VegMeal
Item:VegBurger,Packing:Wrapper,Price:25.0
Item:Coke,Packing:Bottle,Price:30.0
TotalCost:55.0
NonVegMeal
Item:ChickenBurger,Packing:Wrapper,Price:50.5
Item:Pepsi,Packing:Bottle,Price:35.0
TotalCost:85.5
PROTOTYPEPATTERN
Prototypepatternreferstocreatingduplicateobjectwhilekeepingperformanceinmind.Thistypeofdesignpatterncomesundercreational
patternasthispatternprovidesoneofthebestwaytocreateanobject.
Thispatterninvolvesimplementingaprototypeinterfacewhichtellstocreateacloneofthecurrentobject.Thispatternisusedwhencreation
ofobjectdirectlyiscostly.Forexample,aobjectistobecreatedafteracostlydatabaseoperation.Wecancachetheobject,returnsitscloneon
nextrequestandupdatethedatabaseasasandwhenneededthusreducingdatabasecalls.
Implementation
We'regoingtocreateanabstractclassShapeandconcreteclassesextendingtheShapeclass.AclassShapeCacheisdefinedasanextstepwhich
storesshapeobjectsinaHashtableandreturnstheirclonewhenrequested.
PrototypPatternDemo,ourdemoclasswilluseShapeCacheclasstogetaShapeobject.
Step1
CreateanabstractclassimplementingClonableinterface.
Shape.java
publicabstractclassShapeimplementsCloneable{
privateStringid;
protectedStringtype;
abstractvoiddraw();
publicStringgetType(){
returntype;
}
publicStringgetId(){
returnid;
}
publicvoidsetId(Stringid){
this.id=id;
}
publicObjectclone(){
Objectclone=null;
try{
clone=super.clone();
}catch(CloneNotSupportedExceptione){
e.printStackTrace();
}
returnclone;
}
}
Step2
Createconcreteclassesextendingtheaboveclass.
Rectangle.java
publicclassRectangleextendsShape{
publicRectangle(){
type="Rectangle";
}
@Override
publicvoiddraw(){
System.out.println("InsideRectangle::draw()method.");
}
}
Square.java
publicclassSquareextendsShape{
publicSquare(){
type="Square";
}
@Override
publicvoiddraw(){
System.out.println("InsideSquare::draw()method.");
}
}
Circle.java
publicclassCircleextendsShape{
publicCircle(){
type="Circle";
}
@Override
publicvoiddraw(){
System.out.println("InsideCircle::draw()method.");
}
}
Step3
CreateaclasstogetconcreateclassesfromdatabaseandstoretheminaHashtable.
ShapeCache.java
importjava.util.Hashtable;
publicclassShapeCache{
privatestaticHashtable<String,Shape>shapeMap
=newHashtable<String,Shape>();
publicstaticShapegetShape(StringshapeId){
ShapecachedShape=shapeMap.get(shapeId);
return(Shape)cachedShape.clone();
}
//foreachshaperundatabasequeryandcreateshape
//shapeMap.put(shapeKey,shape);
//forexample,weareaddingthreeshapes
publicstaticvoidloadCache(){
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);
}
}
Step4
PrototypePatternDemousesShapeCacheclasstogetclonesofshapesstoredinaHashtable.
PrototypePatternDemo.java
publicclassPrototypePatternDemo{
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());
}
}
Step5
Verifytheoutput.
Shape:Circle
Shape:Square
Shape:Rectangle
ADAPTERPATTERN
Adapterpatternworksasabridgebetweentwoincompatibleinterfaces.Thistypeofdesignpatterncomesunderstructuralpatternasthis
patterncombinesthecapabilityoftwoindependentinterfaces.
Thispatterninvolvesasingleclasswhichisresponsibletojoinfunctionalitiesofindependentorincompatibleinterfaces.Areallifeexample
couldbeacaseofcardreaderwhichactsasanadapterbetweenmemorycardandalaptop.Youpluginsthememorycardintocardreaderand
cardreaderintothelaptopsothatmemorycardcanbereadvialaptop.
WearedemonstratinguseofAdapterpatternviafollowingexampleinwhichanaudioplayerdevicecanplaymp3filesonlyandwantstousean
advancedaudioplayercapableofplayingvlcandmp4files.
Implementation
We'veaninterfaceMediaPlayerinterfaceandaconcreteclassAudioPlayerimplementingtheMediaPlayerinterface.AudioPlayercanplay
mp3formataudiofilesbydefault.
We'rehavinganotherinterfaceAdvancedMediaPlayerandconcreteclassesimplementingtheAdvancedMediaPlayerinterface.Theseclasses
canplayvlcandmp4formatfiles.
WewanttomakeAudioPlayertoplayotherformatsaswell.Toattainthis,we'vecreatedanadapterclassMediaAdapterwhichimplementsthe
MediaPlayerinterfaceandusesAdvancedMediaPlayerobjectstoplaytherequiredformat.
AudioPlayerusestheadapterclassMediaAdapterpassingitthedesiredaudiotypewithoutknowingtheactualclasswhichcanplaythedesired
format.AdapterPatternDemo,ourdemoclasswilluseAudioPlayerclasstoplayvariousformats.
Step1
CreateinterfacesforMediaPlayerandAdvancedMediaPlayer.
MediaPlayer.java
publicinterfaceMediaPlayer{
publicvoidplay(StringaudioType,StringfileName);
}
AdvancedMediaPlayer.java
publicinterfaceAdvancedMediaPlayer{
publicvoidplayVlc(StringfileName);
publicvoidplayMp4(StringfileName);
}
Step2
CreateconcreteclassesimplementingtheAdvancedMediaPlayerinterface.
VlcPlayer.java
publicclassVlcPlayerimplementsAdvancedMediaPlayer{
@Override
publicvoidplayVlc(StringfileName){
System.out.println("Playingvlcfile.Name:"+fileName);
}
@Override
publicvoidplayMp4(StringfileName){
//donothing
}
}
Mp4Player.java
publicclassMp4PlayerimplementsAdvancedMediaPlayer{
@Override
publicvoidplayVlc(StringfileName){
//donothing
}
@Override
publicvoidplayMp4(StringfileName){
System.out.println("Playingmp4file.Name:"+fileName);
}
}
Step3
CreateadapterclassimplementingtheMediaPlayerinterface.
MediaAdapter.java
publicclassMediaAdapterimplementsMediaPlayer{
AdvancedMediaPlayeradvancedMusicPlayer;
publicMediaAdapter(StringaudioType){
if(audioType.equalsIgnoreCase("vlc")){
advancedMusicPlayer=newVlcPlayer();
}elseif(audioType.equalsIgnoreCase("mp4")){
advancedMusicPlayer=newMp4Player();
}
}
@Override
publicvoidplay(StringaudioType,StringfileName){
if(audioType.equalsIgnoreCase("vlc")){
advancedMusicPlayer.playVlc(fileName);
}elseif(audioType.equalsIgnoreCase("mp4")){
advancedMusicPlayer.playMp4(fileName);
}
}
}
Step4
CreateconcreteclassimplementingtheMediaPlayerinterface.
AudioPlayer.java
publicclassAudioPlayerimplementsMediaPlayer{
MediaAdaptermediaAdapter;
@Override
publicvoidplay(StringaudioType,StringfileName){
//inbuiltsupporttoplaymp3musicfiles
if(audioType.equalsIgnoreCase("mp3")){
System.out.println("Playingmp3file.Name:"+fileName);
}
//mediaAdapterisprovidingsupporttoplayotherfileformats
elseif(audioType.equalsIgnoreCase("vlc")
||audioType.equalsIgnoreCase("mp4")){
mediaAdapter=newMediaAdapter(audioType);
mediaAdapter.play(audioType,fileName);
}
else{
System.out.println("Invalidmedia."+
audioType+"formatnotsupported");
}
}
}
Step5
UsetheAudioPlayertoplaydifferenttypesofaudioformats.
AdapterPatternDemo.java
publicclassAdapterPatternDemo{
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");
}
}
Step6
Verifytheoutput.
Playingmp3file.Name:beyondthehorizon.mp3
Playingmp4file.Name:alone.mp4
Playingvlcfile.Name:farfaraway.vlc
Invalidmedia.aviformatnotsupported
BRIDGEPATTERN
Bridgeisusedwhereweneedtodecoupleanabstractionfromitsimplementationsothatthetwocanvaryindependently.Thistypeofdesign
patterncomesunderstructuralpatternasthispatterndecouplesimplementationclassandabstractclassbyprovidingabridgestructure
betweenthem.
Thispatterninvolvesaninterfacewhichactsasabridgewhichmakesthefunctionalityofconcreteclassesindependentfrominterface
implementerclasses.Bothtypesofclassescanbealteredstructurallywithoutaffectingeachother.
WearedemonstratinguseofBridgepatternviafollowingexampleinwhichacirclecanbedrawnindifferentcolorsusingsameabstractclass
methodbutdifferentbridgeimplementerclasses.
Implementation
We'veaninterfaceDrawAPIinterfacewhichisactingasabridgeimplementerandconcreteclassesRedCircle,GreenCircleimplementingthe
DrawAPIinterface.ShapeisanabstractclassandwilluseobjectofDrawAPI.BridgePatternDemo,ourdemoclasswilluseShapeclasstodraw
differentcoloredcircle.
Step1
Createbridgeimplementerinterface.
DrawAPI.java
publicinterfaceDrawAPI{
publicvoiddrawCircle(intradius,intx,inty);
}
Step2
CreateconcretebridgeimplementerclassesimplementingtheDrawAPIinterface.
RedCircle.java
publicclassRedCircleimplementsDrawAPI{
@Override
publicvoiddrawCircle(intradius,intx,inty){
System.out.println("DrawingCircle[color:red,radius:"
+radius+",x:"+x+","+y+"]");
}
}
GreenCircle.java
publicclassGreenCircleimplementsDrawAPI{
@Override
publicvoiddrawCircle(intradius,intx,inty){
System.out.println("DrawingCircle[color:green,radius:"
+radius+",x:"+x+","+y+"]");
}
}
Step3
CreateanabstractclassShapeusingtheDrawAPIinterface.
Shape.java
publicabstractclassShape{
protectedDrawAPIdrawAPI;
protectedShape(DrawAPIdrawAPI){
this.drawAPI=drawAPI;
}
publicabstractvoiddraw();
}
Step4
CreateconcreteclassimplementingtheShapeinterface.
Circle.java
publicclassCircleextendsShape{
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);
}
}
Step5
UsetheShapeandDrawAPIclassestodrawdifferentcoloredcircles.
BridgePatternDemo.java
publicclassBridgePatternDemo{
publicstaticvoidmain(String[]args){
ShaperedCircle=newCircle(100,100,10,newRedCircle());
ShapegreenCircle=newCircle(100,100,10,newGreenCircle());
redCircle.draw();
greenCircle.draw();
}
}
Step6
Verifytheoutput.
DrawingCircle[color:red,radius:10,x:100,100]
DrawingCircle[color:green,radius:10,x:100,100]
FILTER/CRITERIAPATTERN
FilterpatternorCriteriapatternisadesignpatternthatenablesdeveloperstofilterasetofobjects,usingdifferentcriteria,chainingthemina
decoupledwaythroughlogicaloperations.Thistypeofdesignpatterncomesunderstructuralpatternasthispatterniscombiningmultiple
criteriatoobtainsinglecriteria.
Implementation
We'regoingtocreateaPersonobject,CriteriainterfaceandconcreteclassesimplementingthisinterfacetofilterlistofPersonobjects.
CriteriaPatternDemo,ourdemoclassusesCriteriaobjectstofilterListofPersonobjectsbasedonvariouscriteriaandtheircombinations.
Step1
Createaclassonwhichcriteriaistobeapplied.
Person.java
publicclassPerson{
privateStringname;
privateStringgender;
privateStringmaritalStatus;
publicPerson(Stringname,Stringgender,StringmaritalStatus){
this.name=name;
this.gender=gender;
this.maritalStatus=maritalStatus;
}
publicStringgetName(){
returnname;
}
publicStringgetGender(){
returngender;
}
publicStringgetMaritalStatus(){
returnmaritalStatus;
}
}
Step2
CreateaninterfaceforCriteria.
Criteria.java
importjava.util.List;
publicinterfaceCriteria{
publicList<Person>meetCriteria(List<Person>persons);
}
Step3
CreateconcreteclassesimplementingtheCriteriainterface.
CriteriaMale.java
importjava.util.ArrayList;
importjava.util.List;
publicclassCriteriaMaleimplementsCriteria{
@Override
publicList<Person>meetCriteria(List<Person>persons){
List<Person>malePersons=newArrayList<Person>();
for(Personperson:persons){
if(person.getGender().equalsIgnoreCase("MALE")){
malePersons.add(person);
}
}
returnmalePersons;
}
}
CriteriaFemale.java
importjava.util.ArrayList;
importjava.util.List;
publicclassCriteriaFemaleimplementsCriteria{
@Override
publicList<Person>meetCriteria(List<Person>persons){
List<Person>femalePersons=newArrayList<Person>();
for(Personperson:persons){
if(person.getGender().equalsIgnoreCase("FEMALE")){
femalePersons.add(person);
}
}
returnfemalePersons;
}
}
CriteriaSingle.java
importjava.util.ArrayList;
importjava.util.List;
publicclassCriteriaSingleimplementsCriteria{
@Override
publicList<Person>meetCriteria(List<Person>persons){
List<Person>singlePersons=newArrayList<Person>();
for(Personperson:persons){
if(person.getMaritalStatus().equalsIgnoreCase("SINGLE")){
singlePersons.add(person);
}
}
returnsinglePersons;
}
}
AndCriteria.java
importjava.util.List;
publicclassAndCriteriaimplementsCriteria{
privateCriteriacriteria;
privateCriteriaotherCriteria;
publicAndCriteria(Criteriacriteria,CriteriaotherCriteria){
this.criteria=criteria;
this.otherCriteria=otherCriteria;
}
@Override
publicList<Person>meetCriteria(List<Person>persons){
List<Person>firstCriteriaPersons=criteria.meetCriteria(persons);
returnotherCriteria.meetCriteria(firstCriteriaPersons);
}
}
OrCriteria.java
importjava.util.List;
publicclassAndCriteriaimplementsCriteria{
privateCriteriacriteria;
privateCriteriaotherCriteria;
publicAndCriteria(Criteriacriteria,CriteriaotherCriteria){
this.criteria=criteria;
this.otherCriteria=otherCriteria;
}
@Override
publicList<Person>meetCriteria(List<Person>persons){
List<Person>firstCriteriaItems=criteria.meetCriteria(persons);
List<Person>otherCriteriaItems=otherCriteria.meetCriteria(persons);
for(Personperson:otherCriteriaItems){
if(!firstCriteriaItems.contains(person)){
firstCriteriaItems.add(person);
}
}
returnfirstCriteriaItems;
}
}
Step4
UsedifferentCriteriaandtheircombinationtofilteroutpersons.
CriteriaPatternDemo.java
publicclassCriteriaPatternDemo{
publicstaticvoidmain(String[]args){
List<Person>persons=newArrayList<Person>();
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(List<Person>persons){
for(Personperson:persons){
System.out.println("Person:[Name:"+person.getName()
+",Gender:"+person.getGender()
+",MaritalStatus:"+person.getMaritalStatus()
+"]");
}
}
}
Step5
Verifytheoutput.
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]
COMPOSITEPATTERN
Compositepatternisusedwhereweneedtotreatagroupofobjectsinsimilarwayasasingleobject.Compositepatterncomposesobjectsin
termofatreestructuretorepresentpartaswellaswholehierarchy.Thistypeofdesignpatterncomesunderstructuralpatternasthispattern
createsatreestructureofgroupofobjects.
Thispatterncreatesaclasscontainsgroupofitsownobjects.Thisclassprovideswaystomodifyitsgroupofsameobjects.
WearedemonstratinguseofCompositepatternviafollowingexampleinwhichshowemployeeshierarchyofanorganization.
Implementation
We'veaclassEmployeewhichactsascompositepatternactorclass.CompositePatternDemo,ourdemoclasswilluseEmployeeclasstoadd
departmentlevelhierarchyandprintallemployees.
Step1
CreateEmployeeclasshavinglistofEmployeeobjects.
Employee.java
importjava.util.ArrayList;
importjava.util.List;
publicclassEmployee{
privateStringname;
privateStringdept;
privateintsalary;
privateList<Employee>subordinates;
//constructor
publicEmployee(Stringname,Stringdept,intsal){
this.name=name;
this.dept=dept;
this.salary=sal;
subordinates=newArrayList<Employee>();
}
publicvoidadd(Employeee){
subordinates.add(e);
}
publicvoidremove(Employeee){
subordinates.remove(e);
}
publicList<Employee>getSubordinates(){
returnsubordinates;
}
publicStringtoString(){
return("Employee:[Name:"+name
+",dept:"+dept+",salary:"
+salary+"]");
}
}
Step2
UsetheEmployeeclasstocreateandprintemployeehierarchy.
CompositePatternDemo.java
publicclassCompositePatternDemo{
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);
//printallemployeesoftheorganization
System.out.println(CEO);
for(EmployeeheadEmployee:CEO.getSubordinates()){
System.out.println(headEmployee);
for(Employeeemployee:headEmployee.getSubordinates()){
System.out.println(employee);
}
}
}
}
Step3
Verifytheoutput.
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]
DECORATORPATTERN
Decoratorpatternallowstoaddnewfunctionalityanexistingobjectwithoutalteringitsstructure.Thistypeofdesignpatterncomesunder
structuralpatternasthispatternactsasawrappertoexistingclass.
Thispatterncreatesadecoratorclasswhichwrapstheoriginalclassandprovidesadditionalfunctionalitykeepingclassmethodssignature
intact.
WearedemonstratinguseofDecoratorpatternviafollowingexampleinwhichwe'lldecorateashapewithsomecolorwithoutaltershapeclass.
Implementation
We'regoingtocreateaShapeinterfaceandconcreteclassesimplementingtheShapeinterface.Wethencreateaabstractdecoratorclass
ShapeDecoratorimplementingtheShapeinterfaceandhavingShapeobjectasitsinstancevariable.
RedShapeDecoratorisconcreteclassimplementingShapeDecorator.
DecoratorPatternDemo,ourdemoclasswilluseRedShapeDecoratortodecorateShapeobjects.
Step1
Createaninterface.
Shape.java
publicinterfaceShape{
voiddraw();
}
Step2
Createconcreteclassesimplementingthesameinterface.
Rectangle.java
publicclassRectangleimplementsShape{
@Override
publicvoiddraw(){
System.out.println("Shape:Rectangle");
}
}
Circle.java
publicclassCircleimplementsShape{
@Override
publicvoiddraw(){
System.out.println("Shape:Circle");
}
}
Step3
CreateabstractdecoratorclassimplementingtheShapeinterface.
ShapeDecorator.java
publicabstractclassShapeDecoratorimplementsShape{
protectedShapedecoratedShape;
publicShapeDecorator(ShapedecoratedShape){
this.decoratedShape=decoratedShape;
}
publicvoiddraw(){
decoratedShape.draw();
}
}
Step4
CreateconcretedecoratorclassextendingtheShapeDecoratorclass.
RedShapeDecorator.java
publicclassRedShapeDecoratorextendsShapeDecorator{
publicRedShapeDecorator(ShapedecoratedShape){
super(decoratedShape);
}
@Override
publicvoiddraw(){
decoratedShape.draw();
setRedBorder(decoratedShape);
}
privatevoidsetRedBorder(ShapedecoratedShape){
System.out.println("BorderColor:Red");
}
}
Step5
UsetheRedShapeDecoratortodecorateShapeobjects.
DecoratorPatternDemo.java
publicclassDecoratorPatternDemo{
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();
}
}
Step6
Verifytheoutput.
Circlewithnormalborder
Shape:Circle
Circleofredborder
Shape:Circle
BorderColor:Red
Rectangleofredborder
Shape:Rectangle
BorderColor:Red
FACADEPATTERN
Facadepatternhidesthecomplexitiesofthesystemandprovidesaninterfacetotheclientusingwhichtheclientcanaccessthesystem.This
typeofdesignpatterncomesunderstructuralpatternasthispatternaddsaninterfacetoexitingsystemtohideitscomplexities.
Thispatterninvolvesasingleclasswhichprovidessimplifiedmethodswhicharerequiredbyclientanddelegatescallstoexistingsystemclasses
methods.
Implementation
We'regoingtocreateaShapeinterfaceandconcreteclassesimplementingtheShapeinterface.AfacadeclassShapeMakerisdefinedasanext
step.
ShapeMakerclassusestheconcreteclassestodelegatesusercallstotheseclasses.FacadePatternDemo,ourdemoclasswilluseShapeMaker
classtoshowtheresults.
Step1
Createaninterface.
Shape.java
publicinterfaceShape{
voiddraw();
}
Step2
Createconcreteclassesimplementingthesameinterface.
Rectangle.java
publicclassRectangleimplementsShape{
@Override
publicvoiddraw(){
System.out.println("Rectangle::draw()");
}
}
Square.java
publicclassSquareimplementsShape{
@Override
publicvoiddraw(){
System.out.println("Square::draw()");
}
}
Circle.java
publicclassCircleimplementsShape{
@Override
publicvoiddraw(){
System.out.println("Circle::draw()");
}
}
Step3
Createafacadeclass.
ShapeMaker.java
publicclassShapeMaker{
privateShapecircle;
privateShaperectangle;
privateShapesquare;
publicShapeMaker(){
circle=newCircle();
rectangle=newRectangle();
square=newSquare();
}
publicvoiddrawCircle(){
circle.draw();
}
publicvoiddrawRectangle(){
rectangle.draw();
}
publicvoiddrawSquare(){
square.draw();
}
}
Step4
Usethefacadetodrawvarioustypesofshapes.
FacadePatternDemo.java
publicclassFacadePatternDemo{
publicstaticvoidmain(String[]args){
ShapeMakershapeMaker=newShapeMaker();
shapeMaker.drawCircle();
shapeMaker.drawRectangle();
shapeMaker.drawSquare();
}
}
Step5
Verifytheoutput.
Circle::draw()
Rectangle::draw()
Square::draw()
FLYWEIGHTPATTERN
Flyweightpatternisprimarilyusedtoreducethenumberofobjectscreated,todecreasememoryfootprintandincreaseperformance.Thistype
ofdesignpatterncomesunderstructuralpatternasthispatternprovideswaystodecreaseobjectscountthusimprovingapplicationrequired
objectsstructure.
Flyweightpatterntrytoreusealreadyexistingsimilarkindobjectsbystoringthemandcreatesnewobjectwhennomatchingobjectisfound.
We'lldemonstratethispatternbydrawing20circleofdifferentlocationsbutwe'llcreatingonly5objects.Only5colorsareavailablesocolor
propertyisusedtocheckalreadyexistingCircleobjects.
Implementation
We'regoingtocreateaShapeinterfaceandconcreteclassCircleimplementingtheShapeinterface.AfactoryclassShapeFactoryisdefinedasa
nextstep.
ShapeFactoryhaveaHashMapofCirclehavingkeyascoloroftheCircleobject.Wheneverarequestcomestocreateacircleofparticularcolor
toShapeFactory.ShapeFactorychecksthecircleobjectinitsHashMap,ifobjectofCirclefound,thatobjectisreturnedotherwiseanewobject
iscreated,storedinhashmapforfutureuseandreturnedtoclient.
FlyWeightPatternDemo,ourdemoclasswilluseShapeFactorytogetaShapeobject.Itwillpassinformation(red/green/blue/black/
white)toShapeFactorytogetthecircleofdesiredcoloritneeds.
Step1
Createaninterface.
Shape.java
publicinterfaceShape{
voiddraw();
}
Step2
Createconcreteclassimplementingthesameinterface.
Circle.java
publicclassCircleimplementsShape{
privateStringcolor;
privateintx;
privateinty;
privateintradius;
publicCircle(Stringcolor){
this.color=color;
}
publicvoidsetX(intx){
this.x=x;
}
publicvoidsetY(inty){
this.y=y;
}
publicvoidsetRadius(intradius){
this.radius=radius;
}
@Override
publicvoiddraw(){
System.out.println("Circle:Draw()[Color:"+color
+",x:"+x+",y:"+y+",radius:"+radius);
}
}
Step3
CreateaFactorytogenerateobjectofconcreteclassbasedongiveninformation.
ShapeFactory.java
importjava.util.HashMap;
publicclassShapeFactory{
privatestaticfinalHashMap<String,Shape>circleMap=newHashMap();
publicstaticShapegetCircle(Stringcolor){
Circlecircle=(Circle)circleMap.get(color);
if(circle==null){
circle=newCircle(color);
circleMap.put(color,circle);
System.out.println("Creatingcircleofcolor:"+color);
}
returncircle;
}
}
Step4
UsetheFactorytogetobjectofconcreteclassbypassinganinformationsuchascolor.
FlyweightPatternDemo.java
publicclassFlyweightPatternDemo{
privatestaticfinalStringcolors[]=
{"Red","Green","Blue","White","Black"};
publicstaticvoidmain(String[]args){
for(inti=0;i<20;++i){
Circlecircle=
(Circle)ShapeFactory.getCircle(getRandomColor());
circle.setX(getRandomX());
circle.setY(getRandomY());
circle.setRadius(100);
circle.draw();
}
}
privatestaticStringgetRandomColor(){
returncolors[(int)(Math.random()*colors.length)];
}
privatestaticintgetRandomX(){
return(int)(Math.random()*100);
}
privatestaticintgetRandomY(){
return(int)(Math.random()*100);
}
}
Step5
Verifytheoutput.
Creatingcircleofcolor:Black
Circle:Draw()[Color:Black,x:36,y:71,radius:100
Creatingcircleofcolor:Green
Circle:Draw()[Color:Green,x:27,y:27,radius:100
Creatingcircleofcolor:White
Circle:Draw()[Color:White,x:64,y:10,radius:100
Creatingcircleofcolor:Red
Circle:Draw()[Color:Red,x:15,y:44,radius:100
Circle:Draw()[Color:Green,x:19,y:10,radius:100
Circle:Draw()[Color:Green,x:94,y:32,radius:100
Circle:Draw()[Color:White,x:69,y:98,radius:100
Creatingcircleofcolor:Blue
Circle:Draw()[Color:Blue,x:13,y:4,radius:100
Circle:Draw()[Color:Green,x:21,y:21,radius:100
Circle:Draw()[Color:Blue,x:55,y:86,radius:100
Circle:Draw()[Color:White,x:90,y:70,radius:100
Circle:Draw()[Color:Green,x:78,y:3,radius:100
Circle:Draw()[Color:Green,x:64,y:89,radius:100
Circle:Draw()[Color:Blue,x:3,y:91,radius:100
Circle:Draw()[Color:Blue,x:62,y:82,radius:100
Circle:Draw()[Color:Green,x:97,y:61,radius:100
Circle:Draw()[Color:Green,x:86,y:12,radius:100
Circle:Draw()[Color:Green,x:38,y:93,radius:100
Circle:Draw()[Color:Red,x:76,y:82,radius:100
Circle:Draw()[Color:Blue,x:95,y:82,radius:100
PROXYPATTERN
InProxypattern,aclassrepresentsfunctionalityofanotherclass.Thistypeofdesignpatterncomesunderstructuralpattern.
InProxypattern,wecreateobjecthavingoriginalobjecttointerfaceitsfunctionalitytoouterworld.
Implementation
We'regoingtocreateaImageinterfaceandconcreteclassesimplementingtheImageinterface.ProxyImageisaaproxyclasstoreduce
memoryfootprintofRealImageobjectloading.
ProxyPatternDemo,ourdemoclasswilluseProxyImagetogetaImageobjecttoloadanddisplayasitneeds.
Step1
Createaninterface.
Image.java
publicinterfaceImage{
voiddisplay();
}
Step2
Createconcreteclassesimplementingthesameinterface.
RealImage.java
publicclassRealImageimplementsImage{
privateStringfileName;
publicRealImage(StringfileName){
this.fileName=fileName;
loadFromDisk(fileName);
}
@Override
publicvoiddisplay(){
System.out.println("Displaying"+fileName);
}
privatevoidloadFromDisk(StringfileName){
System.out.println("Loading"+fileName);
}
}
ProxyImage.java
publicclassProxyImageimplementsImage{
privateRealImagerealImage;
privateStringfileName;
publicProxyImage(StringfileName){
this.fileName=fileName;
}
@Override
publicvoiddisplay(){
if(realImage==null){
realImage=newRealImage(fileName);
}
realImage.display();
}
}
Step3
UsetheProxyImagetogetobjectofRealImageclasswhenrequired.
ProxyPatternDemo.java
publicclassProxyPatternDemo{
publicstaticvoidmain(String[]args){
Imageimage=newProxyImage("test_10mb.jpg");
//imagewillbeloadedfromdisk
image.display();
System.out.println("");
//imagewillnotbeloadedfromdisk
image.display();
}
}
Step4
Verifytheoutput.
Loadingtest_10mb.jpg
Displayingtest_10mb.jpg
Displayingtest_10mb.jpg
CHAINOFRESPONSIBILITYPATTERN
Asthenamesuggest,thechainofresponsibilitypatterncreatesachainofreceiverobjectsforarequest.Thispatterndecouplessenderand
receiverofarequestbasedontypeofrequest.Thispatterncomesunderbehavioralpatterns.
Inthispattern,normallyeachreceivercontainsreferencetoanotherreceiver.Ifoneobjectcannothandletherequestthenitpassesthesameto
thenextreceiverandsoon.
Implementation
We'vecreatedanabstractclassAbstractLoggerwithaleveloflogging.Thenwe'vecreatedthreetypesofloggersextendingtheAbstractLogger.
Eachloggerchecksthelevelofmessagetoitslevelandprintaccordinglyotherwisedoesnotprintandpassthemessagetoitsnextlogger.
Step1
Createanabstractloggerclass.
AbstractLogger.java
publicabstractclassAbstractLogger{
publicstaticintINFO=1;
publicstaticintDEBUG=2;
publicstaticintERROR=3;
protectedintlevel;
//nextelementinchainorresponsibility
protectedAbstractLoggernextLogger;
publicvoidsetNextLogger(AbstractLoggernextLogger){
this.nextLogger=nextLogger;
}
publicvoidlogMessage(intlevel,Stringmessage){
if(this.level<=level){
write(message);
}
if(nextLogger!=null){
nextLogger.logMessage(level,message);
}
}
abstractprotectedvoidwrite(Stringmessage);
Step2
Createconcreteclassesextendingthelogger.
ConsoleLogger.java
publicclassConsoleLoggerextendsAbstractLogger{
publicConsoleLogger(intlevel){
this.level=level;
}
@Override
protectedvoidwrite(Stringmessage){
System.out.println("StandardConsole::Logger:"+message);
}
}
ErrorLogger.java
publicclassErrorLoggerextendsAbstractLogger{
publicErrorLogger(intlevel){
this.level=level;
}
@Override
protectedvoidwrite(Stringmessage){
System.out.println("ErrorConsole::Logger:"+message);
}
}
FileLogger.java
publicclassFileLoggerextendsAbstractLogger{
publicFileLogger(intlevel){
this.level=level;
}
@Override
protectedvoidwrite(Stringmessage){
System.out.println("File::Logger:"+message);
}
}
Step3
Createdifferenttypesofloggers.Assignthemerrorlevelsandsetnextloggerineachlogger.Nextloggerineachloggerrepresentsthepartof
thechain.
ChainPatternDemo.java
publicclassChainPatternDemo{
privatestaticAbstractLoggergetChainOfLoggers(){
AbstractLoggererrorLogger=newErrorLogger(AbstractLogger.ERROR);
AbstractLoggerfileLogger=newFileLogger(AbstractLogger.DEBUG);
AbstractLoggerconsoleLogger=newConsoleLogger(AbstractLogger.INFO);
errorLogger.setNextLogger(fileLogger);
fileLogger.setNextLogger(consoleLogger);
returnerrorLogger;
}
publicstaticvoidmain(String[]args){
AbstractLoggerloggerChain=getChainOfLoggers();
loggerChain.logMessage(AbstractLogger.INFO,
"Thisisaninformation.");
loggerChain.logMessage(AbstractLogger.DEBUG,
"Thisisandebuglevelinformation.");
loggerChain.logMessage(AbstractLogger.ERROR,
"Thisisanerrorinformation.");
}
}
Step4
Verifytheoutput.
StandardConsole::Logger:Thisisaninformation.
File::Logger:Thisisandebuglevelinformation.
StandardConsole::Logger:Thisisandebuglevelinformation.
ErrorConsole::Logger:Thisisanerrorinformation.
File::Logger:Thisisanerrorinformation.
StandardConsole::Logger:Thisisanerrorinformation.
COMMANDPATTERN
Commandpatternisadatadrivendesignpatternandfallsunderbehavioralpatterncategory.Arequestiswrappedunderaobjectascommand
andpassedtoinvokerobject.Invokerobjectlooksfortheappropriateobjectwhichcanhandlethiscommandandpassthecommandtothe
correspondingobjectandthatobjectexecutesthecommand.
Implementation
We'vecreatedaninterfaceOrderwhichisactingasacommand.We'vecreatedaStockclasswhichactsasarequest.We'veconcretecommand
classesBuyStockandSellStockimplementingOrderinterfacewhichwilldoactualcommandprocessing.AclassBrokeriscreatedwhichactsasa
invokerobject.Itcantakeorderandplaceorders.
Brokerobjectusescommandpatterntoidentifywhichobjectwillexecutewhichcommandbasedontypeofcommand.CommandPatternDemo,
ourdemoclasswilluseBrokerclasstodemonstratecommandpattern.
Step1
Createacommandinterface.
Order.java
publicinterfaceOrder{
voidexecute();
}
Step2
Createarequestclass.
Stock.java
publicclassStock{
privateStringname="ABC";
privateintquantity=10;
publicvoidbuy(){
System.out.println("Stock[Name:"+name+",
Quantity:"+quantity+"]bought");
}
publicvoidsell(){
System.out.println("Stock[Name:"+name+",
Quantity:"+quantity+"]sold");
}
}
Step3
CreateconcreteclassesimplementingtheOrderinterface.
BuyStock.java
publicclassBuyStockimplementsOrder{
privateStockabcStock;
publicBuyStock(StockabcStock){
this.abcStock=abcStock;
}
publicvoidexecute(){
abcStock.buy();
}
}
SellStock.java
publicclassSellStockimplementsOrder{
privateStockabcStock;
publicSellStock(StockabcStock){
this.abcStock=abcStock;
}
publicvoidexecute(){
abcStock.sell();
}
}
Step4
Createcommandinvokerclass.
Broker.java
importjava.util.ArrayList;
importjava.util.List;
publicclassBroker{
privateList<Order>orderList=newArrayList<Order>();
publicvoidtakeOrder(Orderorder){
orderList.add(order);
}
publicvoidplaceOrders(){
for(Orderorder:orderList){
order.execute();
}
orderList.clear();
}
}
Step5
UsetheBrokerclasstotakeandexecutecommands.
CommandPatternDemo.java
publicclassCommandPatternDemo{
publicstaticvoidmain(String[]args){
StockabcStock=newStock();
BuyStockbuyStockOrder=newBuyStock(abcStock);
SellStocksellStockOrder=newSellStock(abcStock);
Brokerbroker=newBroker();
broker.takeOrder(buyStockOrder);
broker.takeOrder(sellStockOrder);
broker.placeOrders();
}
}
Step6
Verifytheoutput.
Stock[Name:ABC,Quantity:10]bought
Stock[Name:ABC,Quantity:10]sold
INTERPRETERPATTERN
Interpreterpatternprovideswaytoevaluatelanguagegrammarorexpression.Thistypeofpatterncomesunderbehavioralpatterns.This
patterninvolvesimplementingaexpressioninterfacewhichtellstointerpretaparticularcontext.ThispatternisusedinSQLparsing,symbol
processingengineetc.
Implementation
We'regoingtocreateaninterfaceExpressionandconcreteclassesimplementingtheExpressioninterface.AclassTerminalExpressionis
definedwhichactsasamaininterpreterofcontextinquestion.OtherclassesOrExpression,AndExpressionareusedtocreatecombinational
expressions.
InterpreterPatternDemo,ourdemoclasswilluseExpressionclasstocreaterulesanddemonstrateparsingofexpressions.
Step1
Createanexpressioninterface.
Expression.java
publicinterfaceExpression{
publicbooleaninterpret(Stringcontext);
}
Step2
Createconcreteclassesimplementingtheaboveinterface.
TerminalExpression.java
publicclassTerminalExpressionimplementsExpression{
privateStringdata;
publicTerminalExpression(Stringdata){
this.data=data;
}
@Override
publicbooleaninterpret(Stringcontext){
if(context.contains(data)){
returntrue;
}
returnfalse;
}
}
OrExpression.java
publicclassOrExpressionimplementsExpression{
privateExpressionexpr1=null;
privateExpressionexpr2=null;
publicOrExpression(Expressionexpr1,Expressionexpr2){
this.expr1=expr1;
this.expr2=expr2;
}
@Override
publicbooleaninterpret(Stringcontext){
returnexpr1.interpret(context)||expr2.interpret(context);
}
}
AndExpression.java
publicclassAndExpressionimplementsExpression{
privateExpressionexpr1=null;
privateExpressionexpr2=null;
publicAndExpression(Expressionexpr1,Expressionexpr2){
this.expr1=expr1;
this.expr2=expr2;
}
@Override
publicbooleaninterpret(Stringcontext){
returnexpr1.interpret(context)&&expr2.interpret(context);
}
}
Step3
InterpreterPatternDemousesExpressionclasstocreaterulesandthenparsethem.
InterpreterPatternDemo.java
publicclassInterpreterPatternDemo{
//Rule:RobertandJohnaremale
publicstaticExpressiongetMaleExpression(){
Expressionrobert=newTerminalExpression("Robert");
Expressionjohn=newTerminalExpression("John");
returnnewOrExpression(robert,john);
}
//Rule:Julieisamarriedwomen
publicstaticExpressiongetMarriedWomanExpression(){
Expressionjulie=newTerminalExpression("Julie");
Expressionmarried=newTerminalExpression("Married");
returnnewAndExpression(julie,married);
}
publicstaticvoidmain(String[]args){
ExpressionisMale=getMaleExpression();
ExpressionisMarriedWoman=getMarriedWomanExpression();
System.out.println("Johnismale?"+isMale.interpret("John"));
System.out.println("Julieisamarriedwomen?"
+isMarriedWoman.interpret("MarriedJulie"));
}
}
Step4
Verifytheoutput.
Johnismale?true
Julieisamarriedwomen?true
ITERATORPATTERN
IteratorpatternisverycommonlyuseddesignpatterninJavaand.Netprogrammingenvironment.Thispatternisusedtogetawaytoaccess
theelementsofacollectionobjectinsequentialmannerwithoutanyneedtoknowitsunderlyingrepresentation.
Iteratorpatternfallsunderbehavioralpatterncategory.
Implementation
We'regoingtocreateaIteratorinterfacewhichnarratesnavigationmethodandaContainerinterfacewhichretrunstheiterator.Concrete
classesimplementingtheContainerinterfacewillberesponsibletoimplementIteratorinterfaceanduseit
IteratorPatternDemo,ourdemoclasswilluseNamesRepository,aconcreteclassimplementationtoprintaNamesstoredasacollectionin
NamesRepository.
Step1
Createinterfaces.
Iterator.java
publicinterfaceIterator{
publicbooleanhasNext();
publicObjectnext();
}
Container.java
publicinterfaceContainer{
publicIteratorgetIterator();
}
Step2
CreateconcreteclassimplementingtheContainerinterface.ThisclasshasinnerclassNameIteratorimplementingtheIteratorinterface.
NameRepository.java
publicclassNameRepositoryimplementsContainer{
publicStringnames[]={"Robert","John","Julie","Lora"};
@Override
publicIteratorgetIterator(){
returnnewNameIterator();
}
privateclassNameIteratorimplementsIterator{
intindex;
@Override
publicbooleanhasNext(){
if(index<names.length){
returntrue;
}
returnfalse;
}
@Override
publicObjectnext(){
if(this.hasNext()){
returnnames[index++];
}
returnnull;
}
}
}
Step3
UsetheNameRepositorytogetiteratorandprintnames.
IteratorPatternDemo.java
publicclassIteratorPatternDemo{
publicstaticvoidmain(String[]args){
NameRepositorynamesRepository=newNameRepository();
for(Iteratoriter=namesRepository.getIterator();iter.hasNext();){
Stringname=(String)iter.next();
System.out.println("Name:"+name);
}
}
}
Step4
Verifytheoutput.
Name:Robert
Name:John
Name:Julie
Name:Lora
MEDIATORPATTERN
Mediatorpatternisusedtoreducecommunicationcomplexitybetweenmultipleobjectsorclasses.Thispatternprovidesamediatorclasswhich
normallyhandlesallthecommunicationsbetweendifferentclassesandsupportseasymaintainabilityofthecodebyloosecoupling.Mediator
patternfallsunderbehavioralpatterncategory.
Implementation
We'redemonstratingmediatorpatternbyexampleofaChatRoomwheremultipleuserscansendmessagetoChatRoomanditisthe
responsibilityofChatRoomtoshowthemessagestoallusers.We'vecreatedtwoclassesChatRoomandUser.UserobjectswilluseChatRoom
methodtosharetheirmessages.
MediatorPatternDemo,ourdemoclasswilluseUserobjectstoshowcommunicationbetweenthem.
Step1
Createmediatorclass.
ChatRoom.java
importjava.util.Date;
publicclassChatRoom{
publicstaticvoidshowMessage(Useruser,Stringmessage){
System.out.println(newDate().toString()
+"["+user.getName()+"]:"+message);
}
}
Step2
Createuserclass
User.java
publicclassUser{
privateStringname;
publicStringgetName(){
returnname;
}
publicvoidsetName(Stringname){
this.name=name;
}
publicUser(Stringname){
this.name=name;
}
publicvoidsendMessage(Stringmessage){
ChatRoom.showMessage(this,message);
}
}
Step3
UsetheUserobjecttoshowcommunicationsbetweenthem.
MediatorPatternDemo.java
publicclassMediatorPatternDemo{
publicstaticvoidmain(String[]args){
Userrobert=newUser("Robert");
Userjohn=newUser("John");
robert.sendMessage("Hi!John!");
john.sendMessage("Hello!Robert!");
}
}
Step4
Verifytheoutput.
ThuJan3116:05:46IST2013[Robert]:Hi!John!
ThuJan3116:05:46IST2013[John]:Hello!Robert!
MEMENTOPATTERN
Mementopatternisusedtoreducewherewewanttorestorestateofanobjecttoapreviousstate.Mementopatternfallsunderbehavioral
patterncategory.
Implementation
Mementopatternusesthreeactorclasses.Mementocontainsstateofanobjecttoberestored.OriginatorcreatesandstoresstatesinMemento
objectsandCaretakerobjectwhichisresponsibletorestoreobjectstatefromMemento.We'vecreatedclassesMemento,Originatorand
CareTaker.
MementoPatternDemo,ourdemoclasswilluseCareTakerandOriginatorobjectstoshowrestorationofobjectstates.
Step1
CreateMementoclass.
Memento.java
publicclassMemento{
privateStringstate;
publicMemento(Stringstate){
this.state=state;
}
publicStringgetState(){
returnstate;
}
}
Step2
CreateOriginatorclass
Originator.java
publicclassOriginator{
privateStringstate;
publicvoidsetState(Stringstate){
this.state=state;
}
publicStringgetState(){
returnstate;
}
publicMementosaveStateToMemento(){
returnnewMemento(state);
}
publicvoidgetStateFromMemento(MementoMemento){
state=Memento.getState();
}
}
Step3
CreateCareTakerclass
CareTaker.java
importjava.util.ArrayList;
importjava.util.List;
publicclassCareTaker{
privateList<Memento>mementoList=newArrayList<Memento>();
publicvoidadd(Mementostate){
mementoList.add(state);
}
publicMementoget(intindex){
returnmementoList.get(index);
}
}
Step4
UseCareTakerandOriginatorobjects.
MementoPatternDemo.java
publicclassMementoPatternDemo{
publicstaticvoidmain(String[]args){
Originatororiginator=newOriginator();
CareTakercareTaker=newCareTaker();
originator.setState("State#1");
originator.setState("State#2");
careTaker.add(originator.saveStateToMemento());
originator.setState("State#3");
careTaker.add(originator.saveStateToMemento());
originator.setState("State#4");
System.out.println("CurrentState:"+originator.getState());
originator.getStateFromMemento(careTaker.get(0));
System.out.println("FirstsavedState:"+originator.getState());
originator.getStateFromMemento(careTaker.get(1));
System.out.println("SecondsavedState:"+originator.getState());
}
}
Step5
Verifytheoutput.
CurrentState:State#4
FirstsavedState:State#2
SecondsavedState:State#3
OBSERVERPATTERN
Observerpatternisusedwhenthereisonetomanyrelationshipbetweenobjectssuchasifoneobjectismodified,itsdepenedentobjectsareto
benotifiedautomatically.Observerpatternfallsunderbehavioralpatterncategory.
Implementation
Observerpatternusesthreeactorclasses.Subject,ObserverandClient.Subject,anobjecthavingmethodstoattachanddeattachobserversto
aclientobject.We'vecreatedclassesSubject,ObserverabstractclassandconcreteclassesextendingtheabstractclasstheObserver.
ObserverPatternDemo,ourdemoclasswilluseSubjectandconcreteclassobjectstoshowobserverpatterninaction.
Step1
CreateSubjectclass.
Subject.java
importjava.util.ArrayList;
importjava.util.List;
publicclassSubject{
privateList<Observer>observers
=newArrayList<Observer>();
privateintstate;
publicintgetState(){
returnstate;
}
publicvoidsetState(intstate){
this.state=state;
notifyAllObservers();
}
publicvoidattach(Observerobserver){
observers.add(observer);
}
publicvoidnotifyAllObservers(){
for(Observerobserver:observers){
observer.update();
}
}
}
Step2
CreateObserverclass.
Observer.java
publicabstractclassObserver{
protectedSubjectsubject;
publicabstractvoidupdate();
}
Step3
Createconcreteobserverclasses
BinaryObserver.java
publicclassBinaryObserverextendsObserver{
publicBinaryObserver(Subjectsubject){
this.subject=subject;
this.subject.attach(this);
}
@Override
publicvoidupdate(){
System.out.println("BinaryString:"
+Integer.toBinaryString(subject.getState()));
}
}
OctalObserver.java
publicclassOctalObserverextendsObserver{
publicOctalObserver(Subjectsubject){
this.subject=subject;
this.subject.attach(this);
}
@Override
publicvoidupdate(){
System.out.println("OctalString:"
+Integer.toOctalString(subject.getState()));
}
}
HexaObserver.java
publicclassHexaObserverextendsObserver{
publicHexaObserver(Subjectsubject){
this.subject=subject;
this.subject.attach(this);
}
@Override
publicvoidupdate(){
System.out.println("HexString:"
+Integer.toHexString(subject.getState()).toUpperCase());
}
}
Step4
UseSubjectandconcreteobserverobjects.
ObserverPatternDemo.java
publicclassObserverPatternDemo{
publicstaticvoidmain(String[]args){
Subjectsubject=newSubject();
newHexaObserver(subject);
newOctalObserver(subject);
newBinaryObserver(subject);
System.out.println("Firststatechange:15");
subject.setState(15);
System.out.println("Secondstatechange:10");
subject.setState(10);
}
}
Step5
Verifytheoutput.
Firststatechange:15
HexString:F
OctalString:17
BinaryString:1111
Secondstatechange:10
HexString:A
OctalString:12
BinaryString:1010
STATEPATTERN
InStatepatternaclassbehaviorchangesbasedonitsstate.Thistypeofdesignpatterncomesunderbehaviorpattern.
InStatepattern,wecreateobjectswhichrepresentvariousstatesandacontextobjectwhosebehaviorvariesasitsstateobjectchanges.
Implementation
We'regoingtocreateaStateinterfacedefiningaactionandconcretestateclassesimplementingtheStateinterface.Contextisaclasswhich
carriesaState.
StaePatternDemo,ourdemoclasswilluseContextandstateobjectstodemonstratechangeinContextbehaviorbasedontypeofstateitisin.
Step1
Createaninterface.
Image.java
publicinterfaceState{
publicvoiddoAction(Contextcontext);
}
Step2
Createconcreteclassesimplementingthesameinterface.
StartState.java
publicclassStartStateimplementsState{
publicvoiddoAction(Contextcontext){
System.out.println("Playerisinstartstate");
context.setState(this);
}
publicStringtoString(){
return"StartState";
}
}
StopState.java
publicclassStopStateimplementsState{
publicvoiddoAction(Contextcontext){
System.out.println("Playerisinstopstate");
context.setState(this);
}
publicStringtoString(){
return"StopState";
}
}
Step3
CreateContextClass.
Context.java
publicclassContext{
privateStatestate;
publicContext(){
state=null;
}
publicvoidsetState(Statestate){
this.state=state;
publicStategetState(){
returnstate;
}
}
Step4
UsetheContexttoseechangeinbehaviourwhenStatechanges.
StatePatternDemo.java
publicclassStatePatternDemo{
publicstaticvoidmain(String[]args){
Contextcontext=newContext();
StartStatestartState=newStartState();
startState.doAction(context);
System.out.println(context.getState().toString());
StopStatestopState=newStopState();
stopState.doAction(context);
System.out.println(context.getState().toString());
}
}
Step5
Verifytheoutput.
Playerisinstartstate
StartState
Playerisinstopstate
StopState
NULLOBJECTPATTERN
InNullObjectpattern,anullobjectreplacescheckofNULLobjectinstance.Insteadofputtingifcheckforanullvalue,NullObjectreflectsado
nothingrelationship.SuchNullobjectcanalsobeusedtoprovidedefaultbehaviourincasedataisnotavailable.
InNullObjectpattern,wecreateaabstractclassspecifyingthevariousoperationstobedone,concreateclassesextendingthisclassandanull
objectclassprovidingdonothingimplementionofthisclassandwillbeusedseemlesslywhereweneedtochecknullvalue.
Implementation
We'regoingtocreateaAbstractCustomerabstractclassdefiningopearations,herethenameofthecustomerandconcreteclassesextendingthe
AbstractCustomerclass.AfactoryclassCustomerFactoryiscreatedtoreturneitherRealCustomerorNullCustomerobjectsbasedonthename
ofcustomerpassedtoit.
NullPatternDemo,ourdemoclasswilluseCustomerFactorytodemonstrateuseofNullObjectpattern.
Step1
Createanabstractclass.
AbstractCustomer.java
publicabstractclassAbstractCustomer{
protectedStringname;
publicabstractbooleanisNil();
publicabstractStringgetName();
}
Step2
Createconcreteclassesextendingtheaboveclass.
RealCustomer.java
publicclassRealCustomerextendsAbstractCustomer{
publicRealCustomer(Stringname){
this.name=name;
}
@Override
publicStringgetName(){
returnname;
}
@Override
publicbooleanisNil(){
returnfalse;
}
}
NullCustomer.java
publicclassNullCustomerextendsAbstractCustomer{
@Override
publicStringgetName(){
return"NotAvailableinCustomerDatabase";
}
@Override
publicbooleanisNil(){
returntrue;
}
}
Step3
CreateCustomerFactoryClass.
CustomerFactory.java
publicclassCustomerFactory{
publicstaticfinalString[]names={"Rob","Joe","Julie"};
publicstaticAbstractCustomergetCustomer(Stringname){
for(inti=0;i<names.length;i++){
if(names[i].equalsIgnoreCase(name)){
returnnewRealCustomer(name);
}
}
returnnewNullCustomer();
}
}
Step4
UsetheCustomerFactorygeteitherRealCustomerorNullCustomerobjectsbasedonthenameofcustomerpassedtoit.
NullPatternDemo.java
publicclassNullPatternDemo{
publicstaticvoidmain(String[]args){
AbstractCustomercustomer1=CustomerFactory.getCustomer("Rob");
AbstractCustomercustomer2=CustomerFactory.getCustomer("Bob");
AbstractCustomercustomer3=CustomerFactory.getCustomer("Julie");
AbstractCustomercustomer4=CustomerFactory.getCustomer("Laura");
System.out.println("Customers");
System.out.println(customer1.getName());
System.out.println(customer2.getName());
System.out.println(customer3.getName());
System.out.println(customer4.getName());
}
}
Step5
Verifytheoutput.
Customers
Rob
NotAvailableinCustomerDatabase
Julie
NotAvailableinCustomerDatabase
STRATEGYPATTERN
InStrategypattern,aclassbehaviororitsalgorithmcanbechangedatruntime.Thistypeofdesignpatterncomesunderbehaviorpattern.
InStrategypattern,wecreateobjectswhichrepresentvariousstrategiesandacontextobjectwhosebehaviorvariesasperitsstrategyobject.
Thestrategyobjectchangestheexecutingalgorithmofthecontextobject.
Implementation
We'regoingtocreateaStrategyinterfacedefiningaactionandconcretestrategyclassesimplementingtheStrategyinterface.Contextisaclass
whichusesaStrategy.
StrategyPatternDemo,ourdemoclasswilluseContextandstrategyobjectstodemonstratechangeinContextbehaviourbasedonstrategyit
deploysoruses.
Step1
Createaninterface.
Strategy.java
publicinterfaceStrategy{
publicintdoOperation(intnum1,intnum2);
}
Step2
Createconcreteclassesimplementingthesameinterface.
OperationAdd.java
publicclassOperationAddimplementsStrategy{
@Override
publicintdoOperation(intnum1,intnum2){
returnnum1+num2;
}
}
OperationSubstract.java
publicclassOperationSubstractimplementsStrategy{
@Override
publicintdoOperation(intnum1,intnum2){
returnnum1num2;
}
}
OperationMultiply.java
publicclassOperationMultiplyimplementsStrategy{
@Override
publicintdoOperation(intnum1,intnum2){
returnnum1*num2;
}
}
Step3
CreateContextClass.
Context.java
publicclassContext{
privateStrategystrategy;
publicContext(Strategystrategy){
this.strategy=strategy;
}
publicintexecuteStrategy(intnum1,intnum2){
returnstrategy.doOperation(num1,num2);
}
}
Step4
UsetheContexttoseechangeinbehaviourwhenitchangesitsStrategy.
StatePatternDemo.java
publicclassStrategyPatternDemo{
publicstaticvoidmain(String[]args){
Contextcontext=newContext(newOperationAdd());
System.out.println("10+5="+context.executeStrategy(10,5));
context=newContext(newOperationSubstract());
System.out.println("105="+context.executeStrategy(10,5));
context=newContext(newOperationMultiply());
System.out.println("10*5="+context.executeStrategy(10,5));
}
}
Step5
Verifytheoutput.
10+5=15
105=5
10*5=50
TEMPLATEPATTERN
InTemplatepattern,anabstractclassexposesdefinedways/templatestoexecuteitsmethods.Itssubclassescanoverridesthemethod
implementationsasperneedbasisbuttheinvocationistobeinthesamewayasdefinedbyanabstractclass.Thispatterncomesunderbehavior
patterncategory.
Implementation
We'regoingtocreateaGameabstractclassdefiningoperationswithatemplatemethodsettobefinalsothatitcannotbeoverridden.Cricket
andFootballareconcreteclassesextendGameandoverrideitsmethods.
TemplatePatternDemo,ourdemoclasswilluseGametodemonstrateuseoftemplatepattern.
Step1
Createanabstractclasswithatemplatemethodbeingfinal.
Game.java
publicabstractclassGame{
abstractvoidinitialize();
abstractvoidstartPlay();
abstractvoidendPlay();
//templatemethod
publicfinalvoidplay(){
//initializethegame
initialize();
//startgame
startPlay();
//endgame
endPlay();
}
}
Step2
Createconcreteclassesextendingtheaboveclass.
Cricket.java
publicclassCricketextendsGame{
@Override
voidendPlay(){
System.out.println("CricketGameFinished!");
}
@Override
voidinitialize(){
System.out.println("CricketGameInitialized!Startplaying.");
}
@Override
voidstartPlay(){
System.out.println("CricketGameStarted.Enjoythegame!");
}
}
Football.java
publicclassFootballextendsGame{
@Override
voidendPlay(){
System.out.println("FootballGameFinished!");
}
@Override
voidinitialize(){
System.out.println("FootballGameInitialized!Startplaying.");
}
@Override
voidstartPlay(){
System.out.println("FootballGameStarted.Enjoythegame!");
}
}
Step3
UsetheGame'stemplatemethodplaytodemonstrateadefinedwayofplayinggame.
TemplatePatternDemo.java
publicclassTemplatePatternDemo{
publicstaticvoidmain(String[]args){
Gamegame=newCricket();
game.play();
System.out.println();
game=newFootball();
game.play();
}
}
Step4
Verifytheoutput.
CricketGameInitialized!Startplaying.
CricketGameStarted.Enjoythegame!
CricketGameFinished!
FootballGameInitialized!Startplaying.
FootballGameStarted.Enjoythegame!
FootballGameFinished!
VISITORPATTERN
InVisitorpattern,weuseavisitorclasswhichchangestheexecutingalgorithmofanelementclass.Bythisway,executionalgorithmofelement
canvariesasvisitorvaries.Thispatterncomesunderbehaviorpatterncategory.Asperthepattern,elementobjecthastoacceptthevisitor
objectsothatvisitorobjecthandlestheoperationontheelementobject.
Implementation
We'regoingtocreateaComputerPartinterfacedefiningacceptopearation.Keyboard,Mouse,MonitorandComputerareconcreteclasses
implementingComputerPartinterface.We'lldefineanotherinterfaceComputerPartVisitorwhichwilldefineavisitorclassoperations.
Computerusesconcretevisitortodocorrespondingaction.
VisitorPatternDemo,ourdemoclasswilluseComputer,ComputerPartVisitorclassestodemonstrateuseofvisitorpattern.
Step1
Defineaninterfacetorepresentelement.
ComputerPart.java
publicinterfaceclassComputerPart{
publicvoidaccept(ComputerPartVisitorcomputerPartVisitor);
}
Step2
Createconcreteclassesextendingtheaboveclass.
Keyboard.java
publicclassKeyboardimplementsComputerPart{
@Override
publicvoidaccept(ComputerPartVisitorcomputerPartVisitor){
computerPartVisitor.visit(this);
}
}
Monitor.java
publicclassMonitorimplementsComputerPart{
@Override
publicvoidaccept(ComputerPartVisitorcomputerPartVisitor){
computerPartVisitor.visit(this);
}
}
Mouse.java
publicclassMouseimplementsComputerPart{
@Override
publicvoidaccept(ComputerPartVisitorcomputerPartVisitor){
computerPartVisitor.visit(this);
}
}
Computer.java
publicclassComputerimplementsComputerPart{
ComputerPart[]parts;
publicComputer(){
parts=newComputerPart[]{newMouse(),newKeyboard(),newMonitor()};
}
@Override
publicvoidaccept(ComputerPartVisitorcomputerPartVisitor){
for(inti=0;i<parts.length;i++){
parts[i].accept(computerPartVisitor);
}
computerPartVisitor.visit(this);
}
}
Step3
Defineaninterfacetorepresentvisitor.
ComputerPartVisitor.java
publicinterfaceComputerPartVisitor{
publicvoidvisit(Computercomputer);
publicvoidvisit(Mousemouse);
publicvoidvisit(Keyboardkeyboard);
publicvoidvisit(Monitormonitor);
}
Step4
Createconcretevisitorimplementingtheaboveclass.
ComputerPartDisplayVisitor.java
publicclassComputerPartDisplayVisitorimplementsComputerPartVisitor{
@Override
publicvoidvisit(Computercomputer){
System.out.println("DisplayingComputer.");
}
@Override
publicvoidvisit(Mousemouse){
System.out.println("DisplayingMouse.");
}
@Override
publicvoidvisit(Keyboardkeyboard){
System.out.println("DisplayingKeyboard.");
}
@Override
publicvoidvisit(Monitormonitor){
System.out.println("DisplayingMonitor.");
}
}
Step5
UsetheComputerPartDisplayVisitortodisplaypartsofComputer.
VisitorPatternDemo.java
publicclassVisitorPatternDemo{
publicstaticvoidmain(String[]args){
ComputerPartcomputer=newComputer();
computer.accept(newComputerPartDisplayVisitor());
}
}
Step6
Verifytheoutput.
DisplayingMouse.
DisplayingKeyboard.
DisplayingMonitor.
DisplayingComputer.
MVCPATTERN
MVCPatternstandsforModelViewControllerPattern.Thispatternisusedtoseparateapplication'sconcerns.
ModelModelrepresentsanobjectorJAVAPOJOcarryingdata.Itcanalsohavelogictoupdatecontrollerifitsdatachanges.
ViewViewrepresentsthevisualizationofthedatathatmodelcontains.
ControllerControlleractsonbothModelandview.Itcontrolsthedataflowintomodelobjectandupdatestheviewwheneverdata
changes.ItkeepsViewandModelseparate.
Implementation
We'regoingtocreateaStudentobjectactingasamodel.StudentViewwillbeaviewclasswhichcanprintstudentdetailsonconsoleand
StudentControlleristhecontrollerclassresponsibletostoredatainStudentobjectandupdateviewStudentViewaccordingly.
MVCPatternDemo,ourdemoclasswilluseStudentControllertodemonstrateuseofMVCpattern.
Step1
CreateModel.
Student.java
publicclassStudent{
privateStringrollNo;
privateStringname;
publicStringgetRollNo(){
returnrollNo;
}
publicvoidsetRollNo(StringrollNo){
this.rollNo=rollNo;
}
publicStringgetName(){
returnname;
}
publicvoidsetName(Stringname){
this.name=name;
}
}
Step2
CreateView.
StudentView.java
publicclassStudentView{
publicvoidprintStudentDetails(StringstudentName,StringstudentRollNo){
System.out.println("Student:");
System.out.println("Name:"+studentName);
System.out.println("RollNo:"+studentRollNo);
}
}
Step3
CreateController.
StudentController.java
publicclassStudentController{
privateStudentmodel;
privateStudentViewview;
publicStudentController(Studentmodel,StudentViewview){
this.model=model;
this.view=view;
}
publicvoidsetStudentName(Stringname){
model.setName(name);
}
publicStringgetStudentName(){
returnmodel.getName();
}
publicvoidsetStudentRollNo(StringrollNo){
model.setRollNo(rollNo);
}
publicStringgetStudentRollNo(){
returnmodel.getRollNo();
}
publicvoidupdateView(){
view.printStudentDetails(model.getName(),model.getRollNo());
}
}
Step4
UsetheStudentControllermethodstodemonstrateMVCdesignpatternusage.
MVCPatternDemo.java
publicclassMVCPatternDemo{
publicstaticvoidmain(String[]args){
//fetchstudentrecordbasedonhisrollnofromthedatabase
Studentmodel=retriveStudentFromDatabase();
//Createaview:towritestudentdetailsonconsole
StudentViewview=newStudentView();
StudentControllercontroller=newStudentController(model,view);
controller.updateView();
//updatemodeldata
controller.setStudentName("John");
controller.updateView();
}
privatestaticStudentretriveStudentFromDatabase(){
Studentstudent=newStudent();
student.setName("Robert");
student.setRollNo("10");
returnstudent;
}
}
Step5
Verifytheoutput.
Student:
Name:Robert
RollNo:10
Student:
Name:Julie
RollNo:10
BUSINESSDELEGATEPATTERN
BusinessDelegatePatternisusedtodecouplepresentationtierandbusinesstier.Itisbasicallyusetoreducecommunicationorremotelookup
functionalitytobusinesstiercodeinpresentationtiercode.Inbusinesstierwe'vefollowingentities.
ClientPresentationtiercodemaybeJSP,servletorUIjavacode.
BusinessDelegateAsingleentrypointclassforcliententitiestoprovideaccesstoBusinessServicemethods.
LookUpServiceLookupserviceobjectisresponsibletogetrelativebusinessimplementationandprovidebusinessobjectaccessto
businessdelegateobject.
BusinessServiceBusinessServiceinterface.Concreteclassesimplementsthisbusinessservicetoprovideactualbusiness
implementationlogic.
Implementation
We'regoingtocreateaClient,BusinessDelegate,BusinessService,LookUpService,JMSServiceandEJBServicerepresentingvariousentities
ofBusinessDelegatepattern.
BusinessDelegatePatternDemo,ourdemoclasswilluseBusinessDelegateandClienttodemonstrateuseofBusinessDelegatepattern.
Step1
CreateBusinessServiceInterface.
BusinessService.java
publicinterfaceBusinessService{
publicvoiddoProcessing();
}
Step2
CreateConcreateServiceClasses.
EJBService.java
publicclassEJBServiceimplementsBusinessService{
@Override
publicvoiddoProcessing(){
System.out.println("ProcessingtaskbyinvokingEJBService");
}
}
JMSService.java
publicclassJMSServiceimplementsBusinessService{
@Override
publicvoiddoProcessing(){
System.out.println("ProcessingtaskbyinvokingJMSService");
}
}
Step3
CreateBusinessLookupService.
BusinessLookUp.java
publicclassBusinessLookUp{
publicBusinessServicegetBusinessService(StringserviceType){
if(serviceType.equalsIgnoreCase("EJB")){
returnnewEJBService();
}else{
returnnewJMSService();
}
}
}
Step4
CreateBusinessDelegate.
BusinessLookUp.java
publicclassBusinessDelegate{
privateBusinessLookUplookupService=newBusinessLookUp();
privateBusinessServicebusinessService;
privateStringserviceType;
publicvoidsetServiceType(StringserviceType){
this.serviceType=serviceType;
}
publicvoiddoTask(){
businessService=lookupService.getBusinessService(serviceType);
businessService.doProcessing();
}
}
Step5
CreateClient.
Student.java
publicclassClient{
BusinessDelegatebusinessService;
publicClient(BusinessDelegatebusinessService){
this.businessService=businessService;
}
publicvoiddoTask(){
businessService.doTask();
}
}
Step6
UseBusinessDelegateandClientclassestodemonstrateBusinessDelegatepattern.
BusinessDelegatePatternDemo.java
publicclassBusinessDelegatePatternDemo{
publicstaticvoidmain(String[]args){
BusinessDelegatebusinessDelegate=newBusinessDelegate();
businessDelegate.setServiceType("EJB");
Clientclient=newClient(businessDelegate);
client.doTask();
businessDelegate.setServiceType("JMS");
client.doTask();
}
}
Step7
Verifytheoutput.
ProcessingtaskbyinvokingEJBService
ProcessingtaskbyinvokingJMSService
COMPOSITEENTITYPATTERN
CompositeEntitypatternisusedinEJBpersistencemechanism.ACompositeentityisanEJBentitybeanwhichrepresentsagraphofobjects.
Whenacompositeentityisupdated,internallydependentobjectsbeansgetupdatedautomaticallyasbeingmanagedbyEJBentitybean.
FollowingaretheparticipantsinCompositeEntityBean.
CompositeEntityItisprimaryentitybean.Itcanbecoarsegrainedorcancontainacoarsegrainedobjecttobeusedforpersistence
purpose.
CoarseGrainedObjectThisobjectcontainsdependentobjects.Ithasitsownlifecycleandalsomanageslifecycleofdependent
objects.
DependentObjectDependentobjectsisanobjectwhichdependsonCoarseGrainedobjectforitspersistencelifecycle.
StrategiesStrategiesrepresentshowtoimplementaCompositeEntity.
Implementation
We'regoingtocreateCompositeEntityobjectactingasCompositeEntity.CoarseGrainedObjectwillbeaclasswhichcontainsdependent
objects.CompositeEntityPatternDemo,ourdemoclasswilluseClientclasstodemonstrateuseofCompositeEntitypattern.
Step1
CreateDependentObjects.
DependentObject1.java
publicclassDependentObject1{
privateStringdata;
publicvoidsetData(Stringdata){
this.data=data;
}
publicStringgetData(){
returndata;
}
}
DependentObject2.java
publicclassDependentObject2{
privateStringdata;
publicvoidsetData(Stringdata){
this.data=data;
}
publicStringgetData(){
returndata;
}
}
Step2
CreateCoarseGrainedObject.
CoarseGrainedObject.java
publicclassCoarseGrainedObject{
DependentObject1do1=newDependentObject1();
DependentObject2do2=newDependentObject2();
publicvoidsetData(Stringdata1,Stringdata2){
do1.setData(data1);
do2.setData(data2);
}
publicString[]getData(){
returnnewString[]{do1.getData(),do2.getData()};
}
}
Step3
CreateCompositeEntity.
CompositeEntity.java
publicclassCompositeEntity{
privateCoarseGrainedObjectcgo=newCoarseGrainedObject();
publicvoidsetData(Stringdata1,Stringdata2){
cgo.setData(data1,data2);
}
publicString[]getData(){
returncgo.getData();
}
}
Step4
CreateClientclasstouseCompositeEntity.
Client.java
publicclassClient{
privateCompositeEntitycompositeEntity=newCompositeEntity();
publicvoidprintData(){
for(inti=0;i<compositeEntity.getData().length;i++){
System.out.println("Data:"+compositeEntity.getData()[i]);
}
}
publicvoidsetData(Stringdata1,Stringdata2){
compositeEntity.setData(data1,data2);
}
}
Step5
UsetheClienttodemonstrateCompositeEntitydesignpatternusage.
CompositeEntityPatternDemo.java
publicclassCompositeEntityPatternDemo{
publicstaticvoidmain(String[]args){
Clientclient=newClient();
client.setData("Test","Data");
client.printData();
client.setData("SecondTest","Data1");
client.printData();
}
}
Step6
Verifytheoutput.
Data:Test
Data:Data
Data:SecondTest
Data:Data1
DATAACCESSOBJECTPATTERN
DataAccessObjectPatternorDAOpatternisusedtoseparatelowleveldataaccessingAPIoroperationsfromhighlevelbusinessservices.
FollowingaretheparticipantsinDataAccessObjectPattern.
DataAccessObjectInterfaceThisinterfacedefinesthestandardoperationstobeperformedonamodelobjects.
DataAccessObjectconcreteclassThisclassimplementsaboveinterface.Thisclassisresponsibletogetdatafromadatasource
whichcanbedatabase/xmloranyotherstoragemechanism.
ModelObjectorValueObjectThisobjectissimplePOJOcontainingget/setmethodstostoredataretrievedusingDAOclass.
Implementation
We'regoingtocreateaStudentobjectactingasaModelorValueObject.StudentDaoisDataAccessObjectInterface.StudentDaoImplis
concreteclassimplementingDataAccessObjectInterface.DaoPatternDemo,ourdemoclasswilluseStudentDaodemonstrateuseofData
AccessObjectpattern.
Step1
CreateValueObject.
Student.java
publicclassStudent{
privateStringname;
privateintrollNo;
Student(Stringname,introllNo){
this.name=name;
this.rollNo=rollNo;
}
publicStringgetName(){
returnname;
}
publicvoidsetName(Stringname){
this.name=name;
}
publicintgetRollNo(){
returnrollNo;
}
publicvoidsetRollNo(introllNo){
this.rollNo=rollNo;
}
}
Step2
CreateDataAccessObjectInterface.
StudentDao.java
importjava.util.List;
publicinterfaceStudentDao{
publicList<Student>getAllStudents();
publicStudentgetStudent(introllNo);
publicvoidupdateStudent(Studentstudent);
publicvoiddeleteStudent(Studentstudent);
}
Step3
Createconcreateclassimplementingaboveinterface.
StudentDaoImpl.java
importjava.util.ArrayList;
importjava.util.List;
publicclassStudentDaoImplimplementsStudentDao{
//listisworkingasadatabase
List<Student>students;
publicStudentDaoImpl(){
students=newArrayList<Student>();
Studentstudent1=newStudent("Robert",0);
Studentstudent2=newStudent("John",1);
students.add(student1);
students.add(student2);
}
@Override
publicvoiddeleteStudent(Studentstudent){
students.remove(student.getRollNo());
System.out.println("Student:RollNo"+student.getRollNo()
+",deletedfromdatabase");
}
//retrivelistofstudentsfromthedatabase
@Override
publicList<Student>getAllStudents(){
returnstudents;
}
@Override
publicStudentgetStudent(introllNo){
returnstudents.get(rollNo);
}
@Override
publicvoidupdateStudent(Studentstudent){
students.get(student.getRollNo()).setName(student.getName());
System.out.println("Student:RollNo"+student.getRollNo()
+",updatedinthedatabase");
}
}
Step4
UsetheStudentDaotodemonstrateDataAccessObjectpatternusage.
CompositeEntityPatternDemo.java
publicclassDaoPatternDemo{
publicstaticvoidmain(String[]args){
StudentDaostudentDao=newStudentDaoImpl();
//printallstudents
for(Studentstudent:studentDao.getAllStudents()){
System.out.println("Student:[RollNo:"
+student.getRollNo()+",Name:"+student.getName()+"]");
}
//updatestudent
Studentstudent=studentDao.getAllStudents().get(0);
student.setName("Michael");
studentDao.updateStudent(student);
//getthestudent
studentDao.getStudent(0);
System.out.println("Student:[RollNo:"
+student.getRollNo()+",Name:"+student.getName()+"]");
}
}
Step5
Verifytheoutput.
Student:[RollNo:0,Name:Robert]
Student:[RollNo:1,Name:John]
Student:RollNo0,updatedinthedatabase
Student:[RollNo:0,Name:Michael]
FRONTCONTROLLERPATTERN
Thefrontcontrollerdesignpatternisusedtoprovideacentralizedrequesthandlingmechanismsothatallrequestswillbehandledbyasingle
handler.Thishandlercandotheauthentication/authorization/loggingortrackingofrequestandthenpasstherequeststocorresponding
handlers.Followingaretheentitiesofthistypeofdesignpattern.
FrontControllerSinglehandlerforallkindofrequestcomingtotheapplicationeitherwebbased/desktopbased .
DispatcherFrontControllermayuseadispatcherobjectwhichcandispatchtherequesttocorrespondingspecifichandler.
ViewViewsaretheobjectforwhichtherequestsaremade.
Implementation
We'regoingtocreateaFrontController,DispatchertoactasFrontControllerandDispatchercorrespondingly.HomeViewandStudentView
representvariousviewsforwhichrequestscancometofrontcontroller.
FrontControllerPatternDemo,ourdemoclasswilluseFrontControlleratodemonstrateFrontControllerDesignPattern.
Step1
CreateViews.
HomeView.java
publicclassHomeView{
publicvoidshow(){
System.out.println("DisplayingHomePage");
}
}
StudentView.java
publicclassStudentView{
publicvoidshow(){
System.out.println("DisplayingStudentPage");
}
}
Step2
CreateDispatcher.
Dispatcher.java
publicclassDispatcher{
privateStudentViewstudentView;
privateHomeViewhomeView;
publicDispatcher(){
studentView=newStudentView();
homeView=newHomeView();
}
publicvoiddispatch(Stringrequest){
if(request.equalsIgnoreCase("STUDENT")){
studentView.show();
}else{
homeView.show();
}
}
}
Step3
CreateFrontController
Context.java
publicclassFrontController{
privateDispatcherdispatcher;
publicFrontController(){
dispatcher=newDispatcher();
}
privatebooleanisAuthenticUser(){
System.out.println("Userisauthenticatedsuccessfully.");
returntrue;
}
privatevoidtrackRequest(Stringrequest){
System.out.println("Pagerequested:"+request);
}
publicvoiddispatchRequest(Stringrequest){
//logeachrequest
trackRequest(request);
//authenticatetheuser
if(isAuthenticUser()){
dispatcher.dispatch(request);
}
}
}
Step4
UsetheFrontControllertodemonstrateFrontControllerDesignPattern.
FrontControllerPatternDemo.java
publicclassFrontControllerPatternDemo{
publicstaticvoidmain(String[]args){
FrontControllerfrontController=newFrontController();
frontController.dispatchRequest("HOME");
frontController.dispatchRequest("STUDENT");
}
}
Step5
Verifytheoutput.
Pagerequested:HOME
Userisauthenticatedsuccessfully.
DisplayingHomePage
Pagerequested:STUDENT
Userisauthenticatedsuccessfully.
DisplayingStudentPage
INTERCEPTINGFILTERPATTERN
Theinterceptingfilterdesignpatternisusedwhenwewanttodosomepreprocessing/postprocessingwithrequestorresponseofthe
application.Filtersaredefinedandappliedontherequestbeforepassingtherequesttoactualtargetapplication.Filterscandothe
authentication/authorization/loggingortrackingofrequestandthenpasstherequeststocorrespondinghandlers.Followingaretheentities
ofthistypeofdesignpattern.
FilterFilterwhichwillperformcertaintaskpriororafterexecutionofrequestbyrequesthandler.
FilterChainFilterChaincarriesmultiplefiltersandhelptoexecutethemindefinedorderontarget.
TargetTargetobjectistherequesthandler
FilterManagerFilterManagermanagesthefiltersandFilterChain.
ClientClientistheobjectwhosendsrequesttotheTargetobject.
Implementation
We'regoingtocreateaFilterChain,FilterManager,Target,Clientasvariousobjectsrepresentingourentities.AuthenticationFilterand
DebugFilterrepresentsconcretefilters.
InterceptingFilterDemo,ourdemoclasswilluseClienttodemonstrateInterceptingFilterDesignPattern.
Step1
CreateFilterinterface.
Filter.java
publicinterfaceFilter{
publicvoidexecute(Stringrequest);
}
Step2
Createconcretefilters.
AuthenticationFilter.java
publicclassAuthenticationFilterimplementsFilter{
publicvoidexecute(Stringrequest){
System.out.println("Authenticatingrequest:"+request);
}
}
DebugFilter.java
publicclassDebugFilterimplementsFilter{
publicvoidexecute(Stringrequest){
System.out.println("requestlog:"+request);
}
}
Step3
CreateTarget
Target.java
publicclassTarget{
publicvoidexecute(Stringrequest){
System.out.println("Executingrequest:"+request);
}
}
Step4
CreateFilterChain
FilterChain.java
importjava.util.ArrayList;
importjava.util.List;
publicclassFilterChain{
privateList<Filter>filters=newArrayList<Filter>();
privateTargettarget;
publicvoidaddFilter(Filterfilter){
filters.add(filter);
}
publicvoidexecute(Stringrequest){
for(Filterfilter:filters){
filter.execute(request);
}
target.execute(request);
}
publicvoidsetTarget(Targettarget){
this.target=target;
}
}
Step5
CreateFilterManager
FilterManager.java
publicclassFilterManager{
FilterChainfilterChain;
publicFilterManager(Targettarget){
filterChain=newFilterChain();
filterChain.setTarget(target);
}
publicvoidsetFilter(Filterfilter){
filterChain.addFilter(filter);
}
publicvoidfilterRequest(Stringrequest){
filterChain.execute(request);
}
}
Step6
CreateClient
Client.java
publicclassClient{
FilterManagerfilterManager;
publicvoidsetFilterManager(FilterManagerfilterManager){
this.filterManager=filterManager;
}
publicvoidsendRequest(Stringrequest){
filterManager.filterRequest(request);
}
}
Step7
UsetheClienttodemonstrateInterceptingFilterDesignPattern.
FrontControllerPatternDemo.java
publicclassInterceptingFilterDemo{
publicstaticvoidmain(String[]args){
FilterManagerfilterManager=newFilterManager(newTarget());
filterManager.setFilter(newAuthenticationFilter());
filterManager.setFilter(newDebugFilter());
Clientclient=newClient();
client.setFilterManager(filterManager);
client.sendRequest("HOME");
}
}
Step8
Verifytheoutput.
Authenticatingrequest:HOME
requestlog:HOME
Executingrequest:HOME
SERVICELOCATORPATTERN
TheservicelocatordesignpatternisusedwhenwewanttolocatevariousservicesusingJNDIlookup.ConsideringhighcostoflookingupJNDI
foraservice,ServiceLocatorpatternmakesuseofcachingtechnique.Forthefirsttimeaserviceisrequired,ServiceLocatorlooksupinJNDI
andcachestheserviceobject.FurtherlookuporsameserviceviaServiceLocatorisdoneinitscachewhichimprovestheperformanceof
applicationtogreatextent.Followingaretheentitiesofthistypeofdesignpattern.
ServiceActualServicewhichwillprocesstherequest.ReferenceofsuchserviceistobelookeduponinJNDIserver.
Context/InitialContextJNDIContext,carriesthereferencetoserviceusedforlookuppurpose.
ServiceLocatorServiceLocatorisasinglepointofcontacttogetservicesbyJNDIlookup,cachingtheservices.
CacheCachetostorereferencesofservicestoreusethem
ClientClientistheobjectwhoinvokestheservicesviaServiceLocator.
Implementation
We'regoingtocreateaServiceLocator,InitialContext,Cache,Serviceasvariousobjectsrepresentingourentities.Service1andService2
representsconcreteservices.
ServiceLocatorPatternDemo,ourdemoclassisactingasaclienthereandwilluseServiceLocatortodemonstrateServiceLocatorDesign
Pattern.
Step1
CreateServiceinterface.
Service.java
publicinterfaceService{
publicStringgetName();
publicvoidexecute();
}
Step2
Createconcreteservices.
Service1.java
publicclassService1implementsService{
publicvoidexecute(){
System.out.println("ExecutingService1");
}
@Override
publicStringgetName(){
return"Service1";
}
}
Service2.java
publicclassService2implementsService{
publicvoidexecute(){
System.out.println("ExecutingService2");
}
@Override
publicStringgetName(){
return"Service2";
}
}
Step3
CreateInitialContextforJNDIlookup
InitialContext.java
publicclassInitialContext{
publicObjectlookup(StringjndiName){
if(jndiName.equalsIgnoreCase("SERVICE1")){
System.out.println("LookingupandcreatinganewService1object");
returnnewService1();
}elseif(jndiName.equalsIgnoreCase("SERVICE2")){
System.out.println("LookingupandcreatinganewService2object");
returnnewService2();
}
returnnull;
}
}
Step4
CreateCache
Cache.java
importjava.util.ArrayList;
importjava.util.List;
publicclassCache{
privateList<Service>services;
publicCache(){
services=newArrayList<Service>();
}
publicServicegetService(StringserviceName){
for(Serviceservice:services){
if(service.getName().equalsIgnoreCase(serviceName)){
System.out.println("Returningcached"+serviceName+"object");
returnservice;
}
}
returnnull;
}
publicvoidaddService(ServicenewService){
booleanexists=false;
for(Serviceservice:services){
if(service.getName().equalsIgnoreCase(newService.getName())){
exists=true;
}
}
if(!exists){
services.add(newService);
}
}
}
Step5
CreateServiceLocator
ServiceLocator.java
publicclassServiceLocator{
privatestaticCachecache;
static{
cache=newCache();
}
publicstaticServicegetService(StringjndiName){
Serviceservice=cache.getService(jndiName);
if(service!=null){
returnservice;
}
InitialContextcontext=newInitialContext();
Serviceservice1=(Service)context.lookup(jndiName);
cache.addService(service1);
returnservice1;
}
}
Step6
UsetheServiceLocatortodemonstrateServiceLocatorDesignPattern.
ServiceLocatorPatternDemo.java
publicclassServiceLocatorPatternDemo{
publicstaticvoidmain(String[]args){
Serviceservice=ServiceLocator.getService("Service1");
service.execute();
service=ServiceLocator.getService("Service2");
service.execute();
service=ServiceLocator.getService("Service1");
service.execute();
service=ServiceLocator.getService("Service2");
service.execute();
}
}
Step7
Verifytheoutput.
LookingupandcreatinganewService1object
ExecutingService1
LookingupandcreatinganewService2object
ExecutingService2
ReturningcachedService1object
ExecutingService1
ReturningcachedService2object
ExecutingService2
TRANSFEROBJECTPATTERN
TheTransferObjectpatternisusedwhenwewanttopassdatawithmultipleattributesinoneshotfromclienttoserver.Transferobjectisalso
knownasValueObject.TransferObjectisasimplePOJOclasshavinggetter/settermethodsandisserializablesothatitcanbetransferredover
thenetwork.Itdonothaveanybehavior.ServerSidebusinessclassnormallyfetchesdatafromthedatabaseandfillsthePOJOandsenditto
theclientorpassitbyvalue.Forclient,transferobjectisreadonly.Clientcancreateitsowntransferobjectandpassittoservertoupdate
valuesindatabaseinoneshot.Followingaretheentitiesofthistypeofdesignpattern.
BusinessObjectBusinessServicewhichfillstheTransferObjectwithdata.
TransferObjectSimplePOJO,havingmethodstoset/getattributesonly.
ClientClienteitherrequestsorsendstheTransferObjecttoBusinessObject.
Implementation
We'regoingtocreateaStudentBOasBusinessObject,StudentasTransferObjectrepresentingourentities.
TransferObjectPatternDemo,ourdemoclassisactingasaclienthereandwilluseStudentBOandStudenttodemonstrateTransferObject
DesignPattern.
Step1
CreateTransferObject.
StudentVO.java
publicclassStudentVO{
privateStringname;
privateintrollNo;
StudentVO(Stringname,introllNo){
this.name=name;
this.rollNo=rollNo;
}
publicStringgetName(){
returnname;
}
publicvoidsetName(Stringname){
this.name=name;
}
publicintgetRollNo(){
returnrollNo;
}
publicvoidsetRollNo(introllNo){
this.rollNo=rollNo;
}
}
Step2
CreateBusinessObject.
StudentBO.java
importjava.util.ArrayList;
importjava.util.List;
publicclassStudentBO{
//listisworkingasadatabase
List<StudentVO>students;
publicStudentBO(){
students=newArrayList<StudentVO>();
StudentVOstudent1=newStudentVO("Robert",0);
StudentVOstudent2=newStudentVO("John",1);
students.add(student1);
students.add(student2);
}
publicvoiddeleteStudent(StudentVOstudent){
students.remove(student.getRollNo());
System.out.println("Student:RollNo"
+student.getRollNo()+",deletedfromdatabase");
}
//retrivelistofstudentsfromthedatabase
publicList<StudentVO>getAllStudents(){
returnstudents;
}
publicStudentVOgetStudent(introllNo){
returnstudents.get(rollNo);
}
publicvoidupdateStudent(StudentVOstudent){
students.get(student.getRollNo()).setName(student.getName());
System.out.println("Student:RollNo"
+student.getRollNo()+",updatedinthedatabase");
}
}
Step3
UsetheStudentBOtodemonstrateTransferObjectDesignPattern.
TransferObjectPatternDemo.java
publicclassTransferObjectPatternDemo{
publicstaticvoidmain(String[]args){
StudentBOstudentBusinessObject=newStudentBO();
//printallstudents
for(StudentVOstudent:studentBusinessObject.getAllStudents()){
System.out.println("Student:[RollNo:"
+student.getRollNo()+",Name:"+student.getName()+"]");
}
//updatestudent
StudentVOstudent=studentBusinessObject.getAllStudents().get(0);
student.setName("Michael");
studentBusinessObject.updateStudent(student);
//getthestudent
studentBusinessObject.getStudent(0);
System.out.println("Student:[RollNo:"
+student.getRollNo()+",Name:"+student.getName()+"]");
}
}
Step4
Verifytheoutput.
Student:[RollNo:0,Name:Robert]
Student:[RollNo:1,Name:John]
Student:RollNo0,updatedinthedatabase
Student:[RollNo:0,Name:Michael]