Java Design Patterns
Java Design Patterns
Abstract Factory Builder Factory Method Prototype Singleton Sets of methods to make various objects. Make and return one object various ways. Methods to make and return components of one object various ways. Make new objects by cloning the objects which you set as prototypes. A class distributes the only instance of itself.
An abstract factory has sets of methods to make families of various objects. In this example the AbstractSoupFactory defines the method names and return types to make various kinds of soup. The BostonConcreteSoupFactory and the HonoluluConcreteSoupFactory both extend the AbstractSoupFactory. An object can be defined as an AbstractSoupFactory, and instantiated as either a BostonConcreteSoupFactory (BCSF) or a HonoluluConcreteSoupFactory (HCSF). Both BCSF or HCSF have the makeFishChowder method, and both return a FishChowder type class. However, the BCSF returns a FishChowder subclass of BostonFishChowder, while the HCSF returns a FishChowder subclass of HonoluluFishChowder. AbstractSoupFactory.java - An Abstract Factory
abstract class AbstractSoupFactory { String factoryLocation; public String getFactoryLocation() { return factoryLocation; } public ChickenSoup makeChickenSoup() { return new ChickenSoup(); } public ClamChowder makeClamChowder() { return new ClamChowder(); } public FishChowder makeFishChowder() { return new FishChowder(); } public Minnestrone makeMinnestrone() { return new Minnestrone(); } public PastaFazul makePastaFazul() { return new PastaFazul(); } public TofuSoup makeTofuSoup() { return new TofuSoup(); } public VegetableSoup makeVegetableSoup() { return new VegetableSoup(); } }
factoryLocation = "Boston"; } public ClamChowder makeClamChowder() { return new BostonClamChowder(); } public FishChowder makeFishChowder() { return new BostonFishChowder(); } } class BostonClamChowder extends ClamChowder { public BostonClamChowder() { soupName = "QuahogChowder"; soupIngredients.clear(); soupIngredients.add("1 Pound Fresh Quahogs"); soupIngredients.add("1 cup corn"); soupIngredients.add("1/2 cup heavy cream"); soupIngredients.add("1/4 cup butter"); soupIngredients.add("1/4 cup potato chips"); } } class BostonFishChowder extends FishChowder { public BostonFishChowder() { soupName = "ScrodFishChowder"; soupIngredients.clear(); soupIngredients.add("1 Pound Fresh Scrod"); soupIngredients.add("1 cup corn"); soupIngredients.add("1/2 cup heavy cream"); soupIngredients.add("1/4 cup butter"); soupIngredients.add("1/4 cup potato chips"); } }
download source, use right-click and "Save Target As..." to save with a .java extension.
} }
soupIngredients.add("1 Pound Fresh Pacific Clams"); soupIngredients.add("1 cup pineapple chunks"); soupIngredients.add("1/2 cup coconut milk"); soupIngredients.add("1/4 cup SPAM"); soupIngredients.add("1/4 cup taro chips");
class HonoluluFishChowder extends FishChowder { public HonoluluFishChowder() { soupName = "OpakapakaFishChowder"; soupIngredients.clear(); soupIngredients.add("1 Pound Fresh Opakapaka Fish"); soupIngredients.add("1 cup pineapple chunks"); soupIngredients.add("1/2 cup coconut milk"); soupIngredients.add("1/4 cup SPAM"); soupIngredients.add("1/4 cup taro chips"); } }
Soup soupOfTheDay = MakeSoupOfTheDay(concreteSoupFactory); System.out.println("The Soup of the day " + concreteSoupFactory.getFactoryLocation() + " is " + soupOfTheDay.getSoupName()); concreteSoupFactory = new HonoluluConcreteSoupFactory(); soupOfTheDay = MakeSoupOfTheDay(concreteSoupFactory); System.out.println("The Soup of the day " + concreteSoupFactory.getFactoryLocation() + " is " + soupOfTheDay.getSoupName());
} }
download source, use right-click and "Save Target As..." to save with a .java extension.
UML
Builder Overview
Make and return one object various ways. In this example the abstract SoupBuffetBuilder defines the methods necessary to create a SoupBuffet. BostonSoupBuffetBuilder and the HonoluluSoupBuffetBuilder both extend the SoupBuffetBuilder. An object can be defined as an SoupBuffetBuilder, and instantiated as either a BostonSoupBuffetBuilder (BSBB) or a HonoluluSoupBuffetBuilder (HSBB). Both BSBB or HSBB have a buildFishChowder method, and both return a FishChowder type class. However, the BSBB returns a FishChowder subclass of BostonFishChowder, while the HSBB returns a FishChowder subclass of HonoluluFishChowder.
SoupBuffetBuilder.java - a Builder
abstract class SoupBuffetBuilder { SoupBuffet soupBuffet; public SoupBuffet getSoupBuffet() { return soupBuffet; } public void buildSoupBuffet() { soupBuffet = new SoupBuffet(); } public abstract void setSoupBuffetName(); public void buildChickenSoup() { soupBuffet.chickenSoup = new ChickenSoup(); } public void buildClamChowder() { soupBuffet.clamChowder = new ClamChowder(); } public void buildFishChowder() { soupBuffet.fishChowder = new FishChowder(); } public void buildMinnestrone() { soupBuffet.minnestrone = new Minnestrone(); } public void buildPastaFazul() { soupBuffet.pastaFazul = new PastaFazul(); } public void buildTofuSoup() { soupBuffet.tofuSoup = new TofuSoup(); } public void buildVegetableSoup() { soupBuffet.vegetableSoup = new VegetableSoup();
} }
download source, use right-click and "Save Target As..." to save with a .java extension.
class BostonClamChowder extends ClamChowder { public BostonClamChowder() { soupName = "QuahogChowder"; soupIngredients.clear(); soupIngredients.add("1 Pound Fresh Quahogs"); soupIngredients.add("1 cup corn"); soupIngredients.add("1/2 cup heavy cream"); soupIngredients.add("1/4 cup butter"); soupIngredients.add("1/4 cup potato chips"); } }
class BostonFishChowder extends FishChowder { public BostonFishChowder() { soupName = "ScrodFishChowder"; soupIngredients.clear(); soupIngredients.add("1 Pound Fresh Scrod"); soupIngredients.add("1 cup corn"); soupIngredients.add("1/2 cup heavy cream"); soupIngredients.add("1/4 cup butter"); soupIngredients.add("1/4 cup potato chips"); } }
download source, use right-click and "Save Target As..." to save with a .java extension.
class HonoluluClamChowder extends ClamChowder { public HonoluluClamChowder() { soupName = "PacificClamChowder"; soupIngredients.clear(); soupIngredients.add("1 Pound Fresh Pacific Clams"); soupIngredients.add("1 cup pineapple chunks"); soupIngredients.add("1/2 cup coconut milk"); soupIngredients.add("1/4 cup SPAM"); soupIngredients.add("1/4 cup taro chips"); } }
class HonoluluFishChowder extends FishChowder { public HonoluluFishChowder() { soupName = "OpakapakaFishChowder"; soupIngredients.clear(); soupIngredients.add("1 Pound Fresh Opakapaka Fish"); soupIngredients.add("1 cup pineapple chunks"); soupIngredients.add("1/2 cup coconut milk"); soupIngredients.add("1/4 cup SPAM"); soupIngredients.add("1/4 cup taro chips"); } }
download source, use right-click and "Save Target As..." to save with a .java extension.
import java.util.ListIterator;
abstract class Soup { ArrayList soupIngredients = new ArrayList(); String soupName; public String getSoupName() { return soupName; } public String toString() { StringBuffer stringOfIngredients = new StringBuffer(soupName); stringOfIngredients.append(" Ingredients: "); ListIterator soupIterator = soupIngredients.listIterator(); while (soupIterator.hasNext()) { stringOfIngredients.append((String)soupIterator.next()); } return stringOfIngredients.toString(); } }
class ChickenSoup extends Soup { public ChickenSoup() { soupName = "ChickenSoup"; soupIngredients.add("1 Pound diced chicken"); soupIngredients.add("1/2 cup rice"); soupIngredients.add("1 cup bullion"); soupIngredients.add("1/16 cup butter"); soupIngredients.add("1/4 cup diced carrots"); } }
class ClamChowder extends Soup { public ClamChowder() { soupName = "ClamChowder"; soupIngredients.add("1 Pound Fresh Clams"); soupIngredients.add("1 cup fruit or vegetables"); soupIngredients.add("1/2 cup milk"); soupIngredients.add("1/4 cup butter"); soupIngredients.add("1/4 cup chips");
} }
class FishChowder extends Soup { public FishChowder() { soupName = "FishChowder"; soupIngredients.add("1 Pound Fresh fish"); soupIngredients.add("1 cup fruit or vegetables"); soupIngredients.add("1/2 cup milk"); soupIngredients.add("1/4 cup butter"); soupIngredients.add("1/4 cup chips"); } }
class Minnestrone extends Soup { public Minnestrone() { soupName = "Minestrone"; soupIngredients.add("1 Pound tomatos"); soupIngredients.add("1/2 cup pasta"); soupIngredients.add("1 cup tomato juice"); } }
class PastaFazul extends Soup { public PastaFazul() { soupName = "Pasta Fazul"; soupIngredients.add("1 Pound tomatos"); soupIngredients.add("1/2 cup pasta"); soupIngredients.add("1/2 cup diced carrots"); soupIngredients.add("1 cup tomato juice"); } }
class TofuSoup extends Soup { public TofuSoup() { soupName = "Tofu Soup"; soupIngredients.add("1 Pound tofu"); soupIngredients.add("1 cup carrot juice"); soupIngredients.add("1/4 cup spirolena");
} }
class VegetableSoup extends Soup { public VegetableSoup() { soupName = "Vegetable Soup"; soupIngredients.add("1 cup bullion"); soupIngredients.add("1/4 cup carrots"); soupIngredients.add("1/4 cup potatoes"); } }
download source, use right-click and "Save Target As..." to save with a .java extension.
public String getSoupBuffetName() { return soupBuffetName; } public void setSoupBuffetName(String soupBuffetNameIn) { soupBuffetName = soupBuffetNameIn; } public void setChickenSoup(ChickenSoup chickenSoup = chickenSoupIn; } public void setClamChowder(ClamChowder clamChowder = clamChowderIn; } public void setFishChowder(FishChowder fishChowder = fishChowderIn; } public void setMinnestrone(Minnestrone minnestrone = minnestroneIn; chickenSoupIn) {
clamChowderIn) {
fishChowderIn) {
minnestroneIn) {
} public void setPastaFazul(PastaFazul pastaFazulIn) { pastaFazul = pastaFazulIn; } public void setTofuSoup(TofuSoup tofuSoupIn) { tofuSoup = tofuSoupIn; } public void setVegetableSoup(VegetableSoup vegetableSoupIn) { vegetableSoup = vegetableSoupIn; } public String getTodaysSoups() { StringBuffer stringOfSoups = new StringBuffer(); stringOfSoups.append(" Today's Soups! "); stringOfSoups.append(" Chicken Soup: "); stringOfSoups.append(this.chickenSoup.getSoupName()); stringOfSoups.append(" Clam Chowder: "); stringOfSoups.append(this.clamChowder.getSoupName()); stringOfSoups.append(" Fish Chowder: "); stringOfSoups.append(this.fishChowder.getSoupName()); stringOfSoups.append(" Minnestrone: "); stringOfSoups.append(this.minnestrone.getSoupName()); stringOfSoups.append(" Pasta Fazul: "); stringOfSoups.append(this.pastaFazul.getSoupName()); stringOfSoups.append(" Tofu Soup: "); stringOfSoups.append(this.tofuSoup.getSoupName()); stringOfSoups.append(" Vegetable Soup: "); stringOfSoups.append(this.vegetableSoup.getSoupName()); return stringOfSoups.toString(); } }
download source, use right-click and "Save Target As..." to save with a .java extension.
public static SoupBuffet CreateSoupBuffet( SoupBuffetBuilder soupBuffetBuilder) { soupBuffetBuilder.buildSoupBuffet(); soupBuffetBuilder.setSoupBuffetName(); soupBuffetBuilder.buildChickenSoup(); soupBuffetBuilder.buildClamChowder(); soupBuffetBuilder.buildFishChowder(); soupBuffetBuilder.buildMinnestrone();
soupBuffetBuilder.buildPastaFazul(); soupBuffetBuilder.buildTofuSoup(); soupBuffetBuilder.buildVegetableSoup(); return soupBuffetBuilder.getSoupBuffet(); } public static void main(String[] args) { SoupBuffet bostonSoupBuffet = CreateSoupBuffet(new BostonSoupBuffetBuilder()); System.out.println("At the " + bostonSoupBuffet.getSoupBuffetName() + bostonSoupBuffet.getTodaysSoups());
Test Results
At the Boston Soup Buffet Today's Soups! Chicken Soup: ChickenSoup Clam Chowder: QuahogChowder Fish Chowder: Scrod FishChowder Minnestrone: Minestrone Pasta Fazul: Pasta Fazul Tofu Soup: Tofu Soup Vegetable Soup: Vegetable Soup
At the Honolulu Soup Buffet Today's Soups! Chicken Soup: ChickenSoup Clam Chowder: PacificClamChowder
Fish Chowder: OpakapakaFishChowder Minnestrone: Minestrone Pasta Fazul: Pasta Fazul Tofu Soup: Tofu Soup Vegetable Soup: Vegetable Soup
UML
Methods to make and return components of one object various ways. In this example the SoupFactoryMethod defines the makeSoupBuffet method which returns a SoupBuffet object. The SoupFactoryMethod also defines the methods needed in creating the SoupBuffet. The BostonSoupFactoryMethodSubclass and the HonoluluSoupFactoryMethodSubclass both extend the SoupFactoryMethod. An object can be defined as an SoupFactoryMethod, and instantiated as either a BostonSoupFactoryMethodSubclass (BSFMS) or a HonoluluSoupFactoryMethodSubclass (HSFMS). Both BSFMS and HSFMS override SoupFactoryMethod's makeFishChowder method. The BSFMS returns a SoupBuffet with a FishChowder subclass of BostonFishChowder, while the HSFMS returns a SoupBuffet with a FishChowder subclass of HonoluluFishChowder.
public ChickenSoup makeChickenSoup() { return new ChickenSoup(); } public ClamChowder makeClamChowder() { return new ClamChowder(); } public FishChowder makeFishChowder() { return new FishChowder(); } public Minnestrone makeMinnestrone() { return new Minnestrone(); } public PastaFazul makePastaFazul() { return new PastaFazul(); } public TofuSoup makeTofuSoup() { return new TofuSoup(); } public VegetableSoup makeVegetableSoup() { return new VegetableSoup();
class BostonClamChowder extends ClamChowder { public BostonClamChowder() { soupName = "QuahogChowder"; soupIngredients.clear(); soupIngredients.add("1 Pound Fresh Quahogs"); soupIngredients.add("1 cup corn"); soupIngredients.add("1/2 cup heavy cream"); soupIngredients.add("1/4 cup butter"); soupIngredients.add("1/4 cup potato chips"); } }
class BostonFishChowder extends FishChowder { public BostonFishChowder() { soupName = "ScrodFishChowder"; soupIngredients.clear(); soupIngredients.add("1 Pound Fresh Scrod"); soupIngredients.add("1 cup corn"); soupIngredients.add("1/2 cup heavy cream"); soupIngredients.add("1/4 cup butter"); soupIngredients.add("1/4 cup potato chips"); } }
download source, use right-click and "Save Target As..." to save with a .java extension.
class HonoluluClamChowder extends ClamChowder { public HonoluluClamChowder() { soupName = "PacificClamChowder"; soupIngredients.clear(); soupIngredients.add("1 Pound Fresh Pacific Clams"); soupIngredients.add("1 cup pineapple chunks"); soupIngredients.add("1/2 cup coconut milk"); soupIngredients.add("1/4 cup SPAM"); soupIngredients.add("1/4 cup taro chips"); } }
class HonoluluFishChowder extends FishChowder { public HonoluluFishChowder() { soupName = "OpakapakaFishChowder"; soupIngredients.clear(); soupIngredients.add("1 Pound Fresh Opakapaka Fish"); soupIngredients.add("1 cup pineapple chunks"); soupIngredients.add("1/2 cup coconut milk"); soupIngredients.add("1/4 cup SPAM"); soupIngredients.add("1/4 cup taro chips"); } }
download source, use right-click and "Save Target As..." to save with a .java extension.
import java.util.ListIterator;
abstract class Soup { ArrayList soupIngredients = new ArrayList(); String soupName; public String getSoupName() { return soupName; } public String toString() { StringBuffer stringOfIngredients = new StringBuffer(soupName); stringOfIngredients.append(" Ingredients: "); ListIterator soupIterator = soupIngredients.listIterator(); while (soupIterator.hasNext()) { stringOfIngredients.append((String)soupIterator.next()); } return stringOfIngredients.toString(); } }
class ChickenSoup extends Soup { public ChickenSoup() { soupName = "ChickenSoup"; soupIngredients.add("1 Pound diced chicken"); soupIngredients.add("1/2 cup rice"); soupIngredients.add("1 cup bullion"); soupIngredients.add("1/16 cup butter"); soupIngredients.add("1/4 cup diced carrots"); } }
class ClamChowder extends Soup { public ClamChowder() { soupName = "ClamChowder"; soupIngredients.add("1 Pound Fresh Clams"); soupIngredients.add("1 cup fruit or vegetables"); soupIngredients.add("1/2 cup milk"); soupIngredients.add("1/4 cup butter"); soupIngredients.add("1/4 cup chips");
} }
class FishChowder extends Soup { public FishChowder() { soupName = "FishChowder"; soupIngredients.add("1 Pound Fresh fish"); soupIngredients.add("1 cup fruit or vegetables"); soupIngredients.add("1/2 cup milk"); soupIngredients.add("1/4 cup butter"); soupIngredients.add("1/4 cup chips"); } }
class Minnestrone extends Soup { public Minnestrone() { soupName = "Minestrone"; soupIngredients.add("1 Pound tomatos"); soupIngredients.add("1/2 cup pasta"); soupIngredients.add("1 cup tomato juice"); } }
class PastaFazul extends Soup { public PastaFazul() { soupName = "Pasta Fazul"; soupIngredients.add("1 Pound tomatos"); soupIngredients.add("1/2 cup pasta"); soupIngredients.add("1/2 cup diced carrots"); soupIngredients.add("1 cup tomato juice"); } }
class TofuSoup extends Soup { public TofuSoup() { soupName = "Tofu Soup"; soupIngredients.add("1 Pound tofu"); soupIngredients.add("1 cup carrot juice"); soupIngredients.add("1/4 cup spirolena");
} }
class VegetableSoup extends Soup { public VegetableSoup() { soupName = "Vegetable Soup"; soupIngredients.add("1 cup bullion"); soupIngredients.add("1/4 cup carrots"); soupIngredients.add("1/4 cup potatoes"); } }
download source, use right-click and "Save Target As..." to save with a .java extension.
public String getSoupBuffetName() { return soupBuffetName; } public void setSoupBuffetName(String soupBuffetNameIn) { soupBuffetName = soupBuffetNameIn; } public void setChickenSoup(ChickenSoup chickenSoup = chickenSoupIn; } public void setClamChowder(ClamChowder clamChowder = clamChowderIn; } public void setFishChowder(FishChowder fishChowder = fishChowderIn; } public void setMinnestrone(Minnestrone minnestrone = minnestroneIn; chickenSoupIn) {
clamChowderIn) {
fishChowderIn) {
minnestroneIn) {
} public void setPastaFazul(PastaFazul pastaFazulIn) { pastaFazul = pastaFazulIn; } public void setTofuSoup(TofuSoup tofuSoupIn) { tofuSoup = tofuSoupIn; } public void setVegetableSoup(VegetableSoup vegetableSoupIn) { vegetableSoup = vegetableSoupIn; } public String getTodaysSoups() { StringBuffer stringOfSoups = new StringBuffer(); stringOfSoups.append(" Today's Soups! "); stringOfSoups.append(" Chicken Soup: "); stringOfSoups.append(this.chickenSoup.getSoupName()); stringOfSoups.append(" Clam Chowder: "); stringOfSoups.append(this.clamChowder.getSoupName()); stringOfSoups.append(" Fish Chowder: "); stringOfSoups.append(this.fishChowder.getSoupName()); stringOfSoups.append(" Minnestrone: "); stringOfSoups.append(this.minnestrone.getSoupName()); stringOfSoups.append(" Pasta Fazul: "); stringOfSoups.append(this.pastaFazul.getSoupName()); stringOfSoups.append(" Tofu Soup: "); stringOfSoups.append(this.tofuSoup.getSoupName()); stringOfSoups.append(" Vegetable Soup: "); stringOfSoups.append(this.vegetableSoup.getSoupName()); return stringOfSoups.toString(); } }
download source, use right-click and "Save Target As..." to save with a .java extension.
public static void main(String[] args) { SoupFactoryMethod soupFactoryMethod = new SoupFactoryMethod(); SoupBuffet soupBuffet = soupFactoryMethod.makeSoupBuffet(); soupBuffet.setSoupBuffetName( soupFactoryMethod.makeBuffetName()); soupBuffet.setChickenSoup( soupFactoryMethod.makeChickenSoup());
soupBuffet.setClamChowder( soupFactoryMethod.makeClamChowder()); soupBuffet.setFishChowder( soupFactoryMethod.makeFishChowder()); soupBuffet.setMinnestrone( soupFactoryMethod.makeMinnestrone()); soupBuffet.setPastaFazul( soupFactoryMethod.makePastaFazul()); soupBuffet.setTofuSoup( soupFactoryMethod.makeTofuSoup()); soupBuffet.setVegetableSoup( soupFactoryMethod.makeVegetableSoup()); System.out.println("At the " + soupBuffet.getSoupBuffetName() + soupBuffet.getTodaysSoups());
SoupFactoryMethod bostonSoupFactoryMethod = new BostonSoupFactoryMethodSubclass(); SoupBuffet bostonSoupBuffet = bostonSoupFactoryMethod.makeSoupBuffet(); bostonSoupBuffet.setSoupBuffetName( bostonSoupFactoryMethod.makeBuffetName()); bostonSoupBuffet.setChickenSoup( bostonSoupFactoryMethod.makeChickenSoup()); bostonSoupBuffet.setClamChowder( bostonSoupFactoryMethod.makeClamChowder()); bostonSoupBuffet.setFishChowder( bostonSoupFactoryMethod.makeFishChowder()); bostonSoupBuffet.setMinnestrone( bostonSoupFactoryMethod.makeMinnestrone()); bostonSoupBuffet.setPastaFazul( bostonSoupFactoryMethod.makePastaFazul()); bostonSoupBuffet.setTofuSoup( bostonSoupFactoryMethod.makeTofuSoup()); bostonSoupBuffet.setVegetableSoup( bostonSoupFactoryMethod.makeVegetableSoup()); System.out.println("At the " + bostonSoupBuffet.getSoupBuffetName() + bostonSoupBuffet.getTodaysSoups()); SoupFactoryMethod honoluluSoupFactoryMethod = new HonoluluSoupFactoryMethodSubclass(); SoupBuffet honoluluSoupBuffet = honoluluSoupFactoryMethod.makeSoupBuffet(); honoluluSoupBuffet.setSoupBuffetName( honoluluSoupFactoryMethod.makeBuffetName()); honoluluSoupBuffet.setChickenSoup( honoluluSoupFactoryMethod.makeChickenSoup()); honoluluSoupBuffet.setClamChowder( honoluluSoupFactoryMethod.makeClamChowder());
honoluluSoupBuffet.setFishChowder( honoluluSoupFactoryMethod.makeFishChowder()); honoluluSoupBuffet.setMinnestrone( honoluluSoupFactoryMethod.makeMinnestrone()); honoluluSoupBuffet.setPastaFazul( honoluluSoupFactoryMethod.makePastaFazul()); honoluluSoupBuffet.setTofuSoup( honoluluSoupFactoryMethod.makeTofuSoup()); honoluluSoupBuffet.setVegetableSoup( honoluluSoupFactoryMethod.makeVegetableSoup()); System.out.println("At the " + honoluluSoupBuffet.getSoupBuffetName() + honoluluSoupBuffet.getTodaysSoups()); } }
download source, use right-click and "Save Target As..." to save with a .java extension.
Test Results
At the Soup Buffet Today's Soups! Chicken Soup: ChickenSoup Clam Chowder: ClamChowder Fish Chowder: FishChowder Minestrone: Minestrone Pasta fazul: Pasta fazul Tofu Soup: Tofu Soup Vegetable Soup: Vegetable Soup
At the
Chicken Soup: ChickenSoup Clam Chowder: QuahogChowder Fish Chowder: ScrodFishChowder Minestrone: Minestrone Pasta fazul: Pasta fazul Tofu Soup: Tofu Soup Vegetable Soup: Vegetable Soup At the Honolulu Soup Buffet Today's Soups! Chicken Soup: ChickenSoup Clam Chowder: PacificClamChowder Fish Chowder: OpakapakaFishChowder
Minnestrone: Minestrone Pasta fazul: Pasta fazul Tofu Soup: Tofu Soup Vegetable Soup: Vegetable Soup
UML
Prototype Overview
Make new objects by cloning the objects which you set as prototypes
Test Results
Creating a Prototype Factory with a SoupSpoon and a SaladFork Getting the Spoon and Fork name: Spoon: Soup Spoon, Fork: Salad Fork Creating a Prototype Factory with a SaladSpoon and a SaladFork Getting the Spoon and Fork name: Spoon: Salad Spoon, Fork: Salad Fork
UML
Singleton Overview
A class distributes the only instance of itself. In this example SingleSpoon class holds one instance of SingleSpoon in "private static SingleSpoon theSpoon;". The SingleSpoon class determines the spoons availability using "private static boolean theSpoonIsAvailable = true;" The first time SingleSpoon.getTheSpoon() is called it creates an instance of a SingleSpoon. The SingleSpoon can not be distributed again until it is returned with SingleSpoon.returnTheSpoon(). If you were to create a spoon "pool" you would have the same basic logic
as shown, however multiple spoons would be distributed. The variable theSpoon would hold an array or collection of spoons. The variable theSpoonIsAvaialable would become a counter of the number of available spoons. Please also note that this example is not thread safe. I think that to make it thread safe all you would need is to make the getTheSpoon() method synchronized. Many thanks to Brian K. for pointing this out.
SingleSpoon.java - a Singleton
public class SingleSpoon { private Soup soupLastUsedWith; private static SingleSpoon theSpoon; private static boolean theSpoonIsAvailable = true; private SingleSpoon() {} public static SingleSpoon getTheSpoon() { if (theSpoonIsAvailable) { if (theSpoon == null) { theSpoon = new SingleSpoon(); } theSpoonIsAvailable = false; return theSpoon; } else { return null; //spoon not available, // could throw error or return null (as shown) } } public String toString() { return "Behold the glorious single spoon!"; } public static void returnTheSpoon() { theSpoon.cleanSpoon(); theSpoonIsAvailable = true; } public Soup getSoupLastUsedWith() { return this.soupLastUsedWith; } public void setSoupLastUsedWith(Soup soup) { this.soupLastUsedWith = soup;
Test Results
First person getting the spoon Behold the glorious single spoon!
UML
TeaBag.java - the class which the adapter will make the adaptee adapt to
public class TeaBag { boolean teaBagIsSteeped; public TeaBag() { teaBagIsSteeped = false; } public void steepTeaInCup() { teaBagIsSteeped = true; System.out.println("tea bag is steeping in cup"); } }
download source, use right-click and "Save Target As..." to save with a .java extension.
TeaCup.java - the class that accepts class TeaBag in it's steepTeaBag() method, and so is being adapted for.
public class TeaCup { public void steepTeaBag(TeaBag teaBag) { teaBag.steepTeaInCup(); } }
download source, use right-click and "Save Target As..." to save with a .java extension.
teaCup.steepTeaBag(teaBag);
System.out.println("Steeping loose leaf tea"); LooseLeafTea looseLeafTea = new LooseLeafTea(); TeaBall teaBall = new TeaBall(looseLeafTea); teaCup.steepTeaBag(teaBall); } }
download source, use right-click and "Save Target As..." to save with a .java extension.
Test Results
Steeping tea bag tea bag is steeping in cup Steeping loose leaf tea tea is steeping
Notes
The basic premise of the adapter is that you either can not or do not want to change the adaptee. This might be because you purchased the adaptee, and do not have the source code. There are two GoF versions of the adapter. The First is the inheriting version, in which the adapter inherits from both "the adaptee" and "the class that adapter will make the adaptee adapt to". The Second is the object version, which is shown here. Reference Design Patterns pages 139-141.
UML
Bridge Overview
An abstraction and implementation are in different class hierarchies.
public class GrapeSodaImp extends SodaImp { GrapeSodaImp() {} public void pourSodaImp() { System.out.println("Delicious Grape Soda!"); } }
download source, use right-click and "Save Target As..." to save with a .java extension.
SodaImpSingleton sodaImpSingleton = new SodaImpSingleton(new CherrySodaImp()); System.out.println( "testing medium soda on the cherry platform"); MediumSoda mediumSoda = new MediumSoda(); mediumSoda.pourSoda(); System.out.println( "testing super size soda on the cherry platform"); SuperSizeSoda superSizeSoda = new SuperSizeSoda(); superSizeSoda.pourSoda(); } public static void testGrapePlatform() { SodaImpSingleton sodaImpSingleton = new SodaImpSingleton(new GrapeSodaImp()); System.out.println( "testing medium soda on the grape platform"); MediumSoda mediumSoda = new MediumSoda(); mediumSoda.pourSoda(); System.out.println( "testing super size soda on the grape platform"); SuperSizeSoda superSizeSoda = new SuperSizeSoda(); superSizeSoda.pourSoda(); } public static void testOrangePlatform() { SodaImpSingleton sodaImpSingleton = new SodaImpSingleton(new OrangeSodaImp()); System.out.println( "testing medium soda on the orange platform"); MediumSoda mediumSoda = new MediumSoda(); mediumSoda.pourSoda(); System.out.println( "testing super size soda on the orange platform"); SuperSizeSoda superSizeSoda = new SuperSizeSoda(); superSizeSoda.pourSoda(); } public static void main(String[] args) { testCherryPlatform(); testGrapePlatform(); testOrangePlatform(); } }
download source, use right-click and "Save Target As..." to save with a .java extension.
Test Results
testing medium soda on the cherry platform ...glug...Yummy Cherry Soda! ...glug...Yummy Cherry Soda! testing super size soda on the cherry platform ...glug...Yummy Cherry Soda! ...glug...Yummy Cherry Soda! ...glug...Yummy Cherry Soda! ...glug...Yummy Cherry Soda! ...glug...Yummy Cherry Soda! testing medium soda on the grape platform ...glug...Delicious Grape Soda! ...glug...Delicious Grape Soda! testing super size soda on the grape platform ...glug...Delicious Grape Soda! ...glug...Delicious Grape Soda! ...glug...Delicious Grape Soda! ...glug...Delicious Grape Soda! ...glug...Delicious Grape Soda! testing medium soda on the orange platform ...glug...Citrusy Orange Soda! ...glug...Citrusy Orange Soda! testing super size soda on the orange platform ...glug...Citrusy Orange Soda! ...glug...Citrusy Orange Soda! ...glug...Citrusy Orange Soda! ...glug...Citrusy Orange Soda! ...glug...Citrusy Orange Soda!
UML
Composite Overview
Assemble groups of objects with the same signature.
public abstract class TeaBags { LinkedList teaBagList; TeaBags parent; String name; public abstract int countTeaBags(); public abstract boolean add(TeaBags teaBagsToAdd); public abstract boolean remove(TeaBags teaBagsToRemove); public abstract ListIterator createListIterator(); public void setParent(TeaBags parentIn) { parent = parentIn; } public TeaBags getParent() { return parent; } public void setName(String nameIn) { name = nameIn; } public String getName() { return name; } }
download source, use right-click and "Save Target As..." to save with a .java extension.
public OneTeaBag(String nameIn) { this.setName(nameIn); } public int countTeaBags() { return 1; } public boolean add(TeaBags teaBagsToAdd) { return false; } public boolean remove(TeaBags teaBagsToRemove) { return false; } public ListIterator createListIterator() { return null; } }
download source, use right-click and "Save Target As..." to save with a .java extension.
public class TinOfTeaBags extends TeaBags { public TinOfTeaBags(String nameIn) { teaBagList = new LinkedList(); this.setName(nameIn); } public int countTeaBags() { int totalTeaBags = 0; ListIterator listIterator = this.createListIterator(); TeaBags tempTeaBags; while (listIterator.hasNext()) { tempTeaBags = (TeaBags)listIterator.next(); totalTeaBags += tempTeaBags.countTeaBags(); } return totalTeaBags; } public boolean add(TeaBags teaBagsToAdd) { teaBagsToAdd.setParent(this); return teaBagList.add(teaBagsToAdd); }
public boolean remove(TeaBags teaBagsToRemove) { ListIterator listIterator = this.createListIterator(); TeaBags tempTeaBags; while (listIterator.hasNext()) { tempTeaBags = (TeaBags)listIterator.next(); if (tempTeaBags == teaBagsToRemove) { listIterator.remove(); return true; } } return false; } public ListIterator createListIterator() { ListIterator listIterator = teaBagList.listIterator(); return listIterator; } }
download source, use right-click and "Save Target As..." to save with a .java extension.
public static void main(String[] args) { System.out.println("Creating tinOfTeaBags"); TeaBags tinOfTeaBags = new TinOfTeaBags("tin of tea bags"); System.out.println("The tinOfTeaBags has " + tinOfTeaBags.countTeaBags() + " tea bags in it.");
System.out.println(" ");
System.out.println("Creating teaBag1"); TeaBags teaBag1 = new OneTeaBag("tea bag 1"); System.out.println("The teaBag1 has " + teaBag1.countTeaBags() + " tea bags in it.");
System.out.println(" ");
System.out.println("Creating teaBag2"); TeaBags teaBag2 = new OneTeaBag("tea bag 2"); System.out.println("The teaBag2 has " + teaBag2.countTeaBags() + " tea bags in it.");
System.out.println(" ");
System.out.println( "Putting teaBag1 and teaBag2 in tinOfTeaBags"); if (tinOfTeaBags.add(teaBag1)) { System.out.println( "teaBag1 added successfully to tinOfTeaBags"); } else { System.out.println( "teaBag1 not added successfully tinOfTeaBags"); } if (tinOfTeaBags.add(teaBag2)) { System.out.println( "teaBag2 added successfully to tinOfTeaBags"); } else { System.out.println( "teaBag2 not added successfully tinOfTeaBags"); } System.out.println("The tinOfTeaBags now has " + tinOfTeaBags.countTeaBags() + " tea bags in it."); System.out.println(" "); System.out.println("Creating smallTinOfTeaBags"); TeaBags smallTinOfTeaBags = new TinOfTeaBags("small tin of tea bags"); System.out.println("The smallTinOfTeaBags has " + smallTinOfTeaBags.countTeaBags() + " tea bags in it."); System.out.println("Creating teaBag3"); TeaBags teaBag3 = new OneTeaBag("tea bag 3"); System.out.println("The teaBag3 has " + teaBag3.countTeaBags() + " tea bags in it."); System.out.println("Putting teaBag3 in smallTinOfTeaBags"); if (smallTinOfTeaBags.add(teaBag3)) { System.out.println( "teaBag3 added successfully to smallTinOfTeaBags"); } else { System.out.println( "teaBag3 not added successfully to smallTinOfTeaBags");
} System.out.println("The smallTinOfTeaBags now has " + smallTinOfTeaBags.countTeaBags() + " tea bags in it."); System.out.println(" "); System.out.println( "Putting smallTinOfTeaBags in tinOfTeaBags"); if (tinOfTeaBags.add(smallTinOfTeaBags)) { System.out.println( "smallTinOfTeaBags added successfully to tinOfTeaBags"); } else { System.out.println( "smallTinOfTeaBags not added successfully to tinOfTeaBags"); } System.out.println("The tinOfTeaBags now has " + tinOfTeaBags.countTeaBags() + " tea bags in it."); System.out.println(" "); System.out.println("Removing teaBag2 from tinOfTeaBags"); if (tinOfTeaBags.remove(teaBag2)) { System.out.println( "teaBag2 successfully removed from tinOfTeaBags"); } else { System.out.println( "teaBag2 not successfully removed from tinOfTeaBags"); } System.out.println("The tinOfTeaBags now has " + tinOfTeaBags.countTeaBags() + " tea bags in it."); } }
download source, use right-click and "Save Target As..." to save with a .java extension.
Test Results
Creating teaBag1 The teaBag1 has 1 tea bags in it. Creating teaBag2 The teaBag2 has 1 tea bags in it. Putting teaBag1 and teaBag2 in tinOfTeaBags teaBag1 added successfully to tinOfTeaBags
teaBag2 added successfully to tinOfTeaBags The tinOfTeaBags now has 2 tea bags in it. Creating smallTinOfTeaBags The smallTinOfTeaBags has 0 tea bags in it. Creating teaBag3 The teaBag3 has 1 tea bags in it. Putting teaBag3 in smallTinOfTeaBags teaBag3 added successfully to smallTinOfTeaBags The smallTinOfTeaBags now has 1 tea bags in it. Putting smallTinOfTeaBags in tinOfTeaBags smallTinOfTeaBags added successfully to tinOfTeaBags The tinOfTeaBags now has 3 tea bags in it. Removing teaBag2 from tinOfTeaBags teaBag2 successfully removed from tinOfTeaBags The tinOfTeaBags now has 2 tea bags in it.
UML
public class ChaiDecorator extends Tea { private Tea teaToMakeChai; private ArrayList chaiIngredients = new ArrayList(); public ChaiDecorator(Tea teaToMakeChai) { this.addTea(teaToMakeChai); chaiIngredients.add("bay leaf"); chaiIngredients.add("cinnamon stick"); chaiIngredients.add("ginger"); chaiIngredients.add("honey"); chaiIngredients.add("soy milk"); chaiIngredients.add("vanilla bean"); }
private void addTea(Tea teaToMakeChaiIn) { this.teaToMakeChai = teaToMakeChaiIn; } public void steepTea() { this.steepChai(); }
public void steepChai() { teaToMakeChai.steepTea(); this.steepChaiIngredients(); System.out.println("tea is steeping with chai"); } public void steepChaiIngredients() { ListIterator listIterator = chaiIngredients.listIterator(); while (listIterator.hasNext()) { System.out.println(((String)(listIterator.next())) + " is steeping"); } System.out.println("chai ingredients are steeping"); } }
download source, use right-click and "Save Target As..." to save with a .java extension.
Test Results
tea leaves are steeping bay leaf is steeping cinnamon stick is steeping ginger is steeping honey is steeping soy milk is steeping vanilla bean is steeping chai ingredients are steeping tea is steeping with chai
UML
Facade Overview
One class has a method that performs a complex process calling several other classes.
FacadeTeaBag facadeTeaBag; public FacadeTeaCup() { setTeaBagIsSteeped(false); System.out.println("behold the beautiful new tea cup"); } public void setTeaBagIsSteeped(boolean isTeaBagSteeped) { teaBagIsSteeped = isTeaBagSteeped; } public boolean getTeaBagIsSteeped() { return teaBagIsSteeped; } public void addFacadeTeaBag(FacadeTeaBag facadeTeaBagIn) { facadeTeaBag = facadeTeaBagIn; System.out.println("the tea bag is in the tea cup"); } public void addFacadeWater(FacadeWater facadeWaterIn) { facadeWater = facadeWaterIn; System.out.println("the water is in the tea cup"); } public void steepTeaBag() { if ( (facadeTeaBag != null) && ( (facadeWater != null) && (facadeWater.getWaterIsBoiling()) ) ) { System.out.println("the tea is steeping in the cup"); setTeaBagIsSteeped(true); } else { System.out.println("the tea is not steeping in the cup"); setTeaBagIsSteeped(false); } } public String toString() { if (this.getTeaBagIsSteeped()) { return ("A nice cuppa tea!"); } else { String tempString = new String("A cup with "); if (facadeWater != null) { if (facadeWater.getWaterIsBoiling()) { tempString = (tempString + "boiling water "); } else { tempString = (tempString + "cold water "); } } else { tempString = (tempString + "no water "); }
if (facadeTeaBag != null) { tempString = (tempString + "and a tea bag"); } else { tempString = (tempString + "and no tea bag"); } return tempString; } } }
download source, use right-click and "Save Target As..." to save with a .java extension.
download source, use right-click and "Save Target As..." to save with a .java extension.
Test Results
FacadeCuppaMaker ready to make you a cuppa! behold the beautiful new tea cup behold the lovely tea bag behold the wonderous water the tea bag is in the tea cup water is boiling the water is in the tea cup the tea is steeping in the cup A nice cuppa tea!
UML
Flyweight Overview
The reusable and variable parts of a class are broken into two classes to save resources.
takeOrders("chai", 2); takeOrders("chai", 2); takeOrders("camomile", 1); takeOrders("camomile", 1); takeOrders("earl grey", 1); takeOrders("camomile", 897); takeOrders("chai", 97); takeOrders("chai", 97); takeOrders("camomile", 3); takeOrders("earl grey", 3); takeOrders("chai", 3); takeOrders("earl grey", 96); takeOrders("camomile", 552); takeOrders("chai", 121); takeOrders("earl grey", 121); for (int i = 0; i < ordersMade; i++) { flavors[i].serveTea(tables[i]); } System.out.println(" "); System.out.println("total teaFlavor objects made: " + teaFlavorFactory.getTotalTeaFlavorsMade()); } }
download source, use right-click and "Save Target As..." to save with a .java extension.
Test Results
Serving Serving Serving Serving Serving Serving Serving Serving Serving Serving Serving Serving Serving Serving Serving tea tea tea tea tea tea tea tea tea tea tea tea tea tea tea flavor flavor flavor flavor flavor flavor flavor flavor flavor flavor flavor flavor flavor flavor flavor chai to table number 2 chai to table number 2 camomile to table number 1 camomile to table number 1 earl grey to table number 1 camomile to table number 897 chai to table number 97 chai to table number 97 camomile to table number 3 earl grey to table number 3 chai to table number 3 earl grey to table number 96 camomile to table number 552 chai to table number 121 earl grey to table number 121
Notes
In this example a single class could have held both the tea flavor and table number. However, we will have a limited number of instances of tea flavors, and so that is broken into a it's own flyweight class. Table number is less limited, so it goes into the context. The factory is responsible for only making one instance of each flyweight. The client is responsible for keeping both halves matched up, and passing the context into the flyweight.
UML
Test Results
Notes
There are four types of proxies, all taking the same basic format: 1. Virtual Proxy - The proxy won't create an "expensive" subject object until it is actually needed. 2. Remote Proxy - A local proxy object controls access to a remote subject object. 3. Protection proxy - The proxy insures that the object creating/calling the subject has authorization to do so. 4. Smart reference - The proxy will perform "additional actions" when the subject is called. Reference Desgin Patterns pages 208-209.
UML
return parent.getTopTitle(); } } }
download source, use right-click and "Save Target As..." to save with a .java extension.
} public void setTopSubCategoryTitle( String topSubCategoryTitleIn) { parent.setTopSubCategoryTitle(topSubCategoryTitleIn); } public String getTopSubCategoryTitle() { return parent.getTopSubCategoryTitle(); } public void setTopCategoryTitle(String topCategoryTitleIn) { parent.setTopCategoryTitle(topCategoryTitleIn); } public String getTopCategoryTitle() { return parent.getTopCategoryTitle(); }
public String getTopTitle() { if (null != getTopSubSubCategoryTitle()) { return this.getTopSubSubCategoryTitle(); } else { System.out.println( "no top title in Category/SubCategory/SubSubCategory " + getAllCategories()); return parent.getTopTitle(); } } }
download source, use right-click and "Save Target As..." to save with a .java extension.
System.out.println(""); System.out.println("Getting top comedy title:"); topTitle = comedy.getTopTitle(); System.out.println("The top title for " + comedy.getAllCategories() + " is " + topTitle);
System.out.println(""); System.out.println("Getting top comedy/childrens title:"); topTitle = comedyChildrens.getTopTitle(); System.out.println("The top title for " + comedyChildrens.getAllCategories() + " is " + topTitle);
System.out.println(""); System.out.println( "Getting top comedy/childrens/aquatic title:"); topTitle = comedyChildrensAquatic.getTopTitle(); System.out.println("The top title for " + comedyChildrensAquatic.getAllCategories() + " is " + topTitle); } }
download source, use right-click and "Save Target As..." to save with a .java extension.
Test Results
Getting top comedy title: The top title for Comedy is Ghost World
Getting top comedy/childrens title: no top title in Category/SubCategory Comedy/Childrens The top title for Comedy/Childrens is Ghost World
Getting top comedy/childrens/aquatic title: The top title for Comedy/Childrens/Aquatic is Sponge Bob Squarepants
UML
class TestCommand { public static void main(String[] args) { DvdName jayAndBob = new DvdName("Jay and Silent Bob Strike Back"); DvdName spongeBob = new DvdName("Sponge Bob Squarepants - " + "Nautical Nonsense and Sponge Buddies"); System.out.println("as first instantiated"); System.out.println(jayAndBob.toString()); System.out.println(spongeBob.toString()); CommandAbstract bobStarsOn = new DvdCommandNameStarsOn(jayAndBob); CommandAbstract bobStarsOff = new DvdCommandNameStarsOff(jayAndBob); CommandAbstract spongeStarsOn = new DvdCommandNameStarsOn(spongeBob); CommandAbstract spongeStarsOff = new DvdCommandNameStarsOff(spongeBob);
Test Results
as first instantiated DVD: Jay and Silent Bob Strike Back DVD: Sponge Bob Squarepants - Nautical Nonsense and Sponge Buddies stars on
DVD: Jay*and*Silent*Bob*Strike*Back DVD: Sponge*Bob*Squarepants*-*Nautical*Nonsense*and*Sponge*Buddies sponge stars off DVD: Jay*and*Silent*Bob*Strike*Back DVD: Sponge Bob Squarepants - Nautical Nonsense and Sponge Buddies
UML
Interpreter Overview
Define a macro language and syntax, parsing input into objects which perform the correct opertaions.
public class DvdInterpreterClient { DvdInterpreterContext dvdInterpreterContext; public DvdInterpreterClient( DvdInterpreterContext dvdInterpreterContext) { this.dvdInterpreterContext = dvdInterpreterContext; } // expression syntax: // show title | actor [for actor | title ] public String interpret(String expression) { StringBuffer result = new StringBuffer("Query Result: "); String currentToken; StringTokenizer expressionTokens = new StringTokenizer(expression); char mainQuery = ' '; char subQuery = ' ';
boolean forUsed = false; String searchString = null; boolean searchStarted = false; boolean searchEnded = false; while (expressionTokens.hasMoreTokens()) { currentToken = expressionTokens.nextToken(); if (currentToken.equals("show")) { continue; //show in all queries, not really used } else if (currentToken.equals("title")) { if (mainQuery == ' ') { mainQuery = 'T'; } else { if ((subQuery == ' ') && (forUsed)) { subQuery = 'T'; } } } else if (currentToken.equals("actor")) { if (mainQuery == ' ') { mainQuery = 'A'; } else { if ((subQuery == ' ') && (forUsed)) { subQuery = 'A'; } } } else if (currentToken.equals("for")) { forUsed = true; } else if ((searchString == null) && (subQuery != ' ') && (currentToken.startsWith("<"))) { searchString = currentToken; searchStarted = true; if (currentToken.endsWith(">")) { searchEnded = true; } } else if ((searchStarted) && (!searchEnded)) { searchString = searchString + " " + currentToken; if (currentToken.endsWith(">")) { searchEnded = true; } } }
DvdAbstractExpression abstractExpression; switch (mainQuery) { case 'A' : { switch (subQuery) { case 'T' : { abstractExpression = new DvdActorTitleExpression(searchString); break; } default : { abstractExpression = new DvdActorExpression(); break; } } break; } case 'T' : { switch (subQuery) { case 'A' : { abstractExpression = new DvdTitleActorExpression(searchString); break; } default : { abstractExpression = new DvdTitleExpression(); break; } } break; } default : return result.toString(); }
public class DvdInterpreterContext { private ArrayList titles = new ArrayList(); private ArrayList actors = new ArrayList(); private ArrayList titlesAndActors = new ArrayList(); public void addTitle(String title) { titles.add(title); } public void addActor(String actor) { actors.add(actor); } public void addTitleAndActor(TitleAndActor titleAndActor) { titlesAndActors.add(titleAndActor); } public ArrayList getAllTitles() { return titles; } public ArrayList getAllActors() { return actors; } public ArrayList getActorsForTitle(String titleIn) { ArrayList actorsForTitle = new ArrayList(); TitleAndActor tempTitleAndActor; ListIterator titlesAndActorsIterator = titlesAndActors.listIterator(); while (titlesAndActorsIterator.hasNext()) { tempTitleAndActor = (TitleAndActor)titlesAndActorsIterator.next(); if (titleIn.equals(tempTitleAndActor.getTitle())) { actorsForTitle.add(tempTitleAndActor.getActor()); } } return actorsForTitle; } public ArrayList getTitlesForActor(String actorIn) { ArrayList titlesForActor = new ArrayList(); TitleAndActor tempTitleAndActor; ListIterator actorsAndTitlesIterator = titlesAndActors.listIterator(); while (actorsAndTitlesIterator.hasNext()) { tempTitleAndActor = (TitleAndActor)actorsAndTitlesIterator.next(); if (actorIn.equals(tempTitleAndActor.getActor())) { titlesForActor.add(tempTitleAndActor.getTitle()); } }
return titlesForActor; } }
download source, use right-click and "Save Target As..." to save with a .java extension.
public class DvdActorExpression extends DvdAbstractExpression { public String interpret(DvdInterpreterContext dvdInterpreterContext) { ArrayList actors = dvdInterpreterContext.getAllActors(); ListIterator actorsIterator = actors.listIterator(); StringBuffer titleBuffer = new StringBuffer(""); boolean first = true; while (actorsIterator.hasNext()) { if (!first) { titleBuffer.append(", "); } else { first = false; } titleBuffer.append((String)actorsIterator.next()); } return titleBuffer.toString(); } }
download source, use right-click and "Save Target As..." to save with a .java extension.
public class DvdActorTitleExpression extends DvdAbstractExpression { String title; public DvdActorTitleExpression(String title) { this.title = title; } public String interpret(DvdInterpreterContext dvdInterpreterContext) { ArrayList actorsAndTitles = dvdInterpreterContext.getActorsForTitle(title); ListIterator actorsAndTitlesIterator = actorsAndTitles.listIterator(); StringBuffer actorBuffer = new StringBuffer(""); boolean first = true; while (actorsAndTitlesIterator.hasNext()) { if (!first) { actorBuffer.append(", "); } else { first = false; } actorBuffer.append((String)actorsAndTitlesIterator.next()); } return actorBuffer.toString(); } }
download source, use right-click and "Save Target As..." to save with a .java extension.
public class DvdTitleExpression extends DvdAbstractExpression { public String interpret(DvdInterpreterContext dvdInterpreterContext) { ArrayList titles = dvdInterpreterContext.getAllTitles(); ListIterator titlesIterator = titles.listIterator();
StringBuffer titleBuffer = new StringBuffer(""); boolean first = true; while (titlesIterator.hasNext()) { if (!first) { titleBuffer.append(", "); } else { first = false; } titleBuffer.append((String)titlesIterator.next()); } return titleBuffer.toString(); } }
download source, use right-click and "Save Target As..." to save with a .java extension.
public class DvdTitleActorExpression extends DvdAbstractExpression { String title; public DvdTitleActorExpression(String title) { this.title = title; } public String interpret(DvdInterpreterContext dvdInterpreterContext) { ArrayList titlesAndActors = dvdInterpreterContext.getTitlesForActor(title); ListIterator titlesAndActorsIterator = titlesAndActors.listIterator(); StringBuffer titleBuffer = new StringBuffer(""); boolean first = true; while (titlesAndActorsIterator.hasNext()) { if (!first) { titleBuffer.append(", "); } else { first = false; } titleBuffer.append((String)titlesAndActorsIterator.next()); } return titleBuffer.toString(); } }
download source, use right-click and "Save Target As..." to save with a .java extension.
dvdInterpreterContext.addActor("Ethan Hawke"); dvdInterpreterContext.addActor("Denzel Washington"); dvdInterpreterContext.addTitleAndActor( new TitleAndActor("Hamlet", "Ethan Hawke")); dvdInterpreterContext.addTitleAndActor( new TitleAndActor("Training Day", "Ethan Hawke")); dvdInterpreterContext.addTitleAndActor( new TitleAndActor("Caddy Shack", "Ethan Hawke")); dvdInterpreterContext.addTitleAndActor( new TitleAndActor("Training Day", "Denzel Washington")); DvdInterpreterClient dvdInterpreterClient =
new DvdInterpreterClient(dvdInterpreterContext); System.out.println( "interpreting show actor: " + dvdInterpreterClient.interpret( "show actor")); System.out.println( "interpreting show actor for title : " + dvdInterpreterClient.interpret( "show actor for title ")); System.out.println( "interpreting show title: " + dvdInterpreterClient.interpret( "show title")); System.out.println( "interpreting show title for actor : " + dvdInterpreterClient.interpret( "show title for actor ")); } }
download source, use right-click and "Save Target As..." to save with a .java extension.
Test Results
interpreting show actor: Query Result: Ethan Hawke, Denzel Washington interpreting show actor for title : Query Result: Ethan Hawke, Denzel Washington interpreting show title: Query Result: Caddy Shack, Training Day, Hamlet interpreting show title for actor : Query Result: Hamlet, Training Day, Caddy Shack
UML
} titles[titleCount++] = titleIn; } public void delete(String titleIn) { boolean found = false; for (int i = 0; i < (titleCount -1); i++) { if (found == false) { if (titles[i].equals(titleIn)) { found = true; titles[i] = titles[i + 1]; } } else { if (i < (titleCount -1)) { titles[i] = titles[i + 1]; } else { titles[i] = null; } } } if (found == true) { --titleCount; } }
//note: // This example shows the Concrete Iterator as an inner class. // The Iterator Pattern in GoF does allow for multiple types of // iterators for a given list or "Aggregate". This could be // accomplished with multiple Iterators in multiple inner classes. // The createIterator class would then have multiple variations. // This, however, assumes that you will have a limited number of // iterator variants - which is normally the case. If you do want // more flexibility in iterator creation, the iterators should not // be in inner classes, and perhaps some sort factory should be // employed to create them. // private class InnerIterator implements DvdListIterator { private int currentPosition = 0; private InnerIterator() {} public void first() { currentPosition = 0;
} public void next() { if (currentPosition < (titleCount)) { ++currentPosition; } } public boolean isDone() { if (currentPosition >= (titleCount)) { return true; } else { return false; } } public String currentItem() { return titles[currentPosition]; } } }
download source, use right-click and "Save Target As..." to save with a .java extension.
fiveShakespeareMovies.delete("American Pie 2"); System.out.println(" "); fiveShakespeareIterator.first(); while (!fiveShakespeareIterator.isDone()) { System.out.println(fiveShakespeareIterator.currentItem()); fiveShakespeareIterator.next(); } } }
download source, use right-click and "Save Target As..." to save with a .java extension.
Test Results
10 Things I Hate About You Shakespeare In Love O (2001) American Pie 2 Scotland, PA. Hamlet (2000) 10 Things I Hate About You Shakespeare In Love O (2001) Scotland, PA. Hamlet (2000)
UML
Mediator Overview
Passes communication between two or more objects.
public abstract class DvdTitle { private String title; public void setTitle(String titleIn) { this.title = titleIn; } public String getTitle() { return this.title; }
download source, use right-click and "Save Target As..." to save with a .java extension.
download source, use right-click and "Save Target As..." to save with a .java extension.
public class DvdUpcaseTitle extends DvdTitle { private String upcaseTitle; private DvdMediator dvdMediator; public DvdUpcaseTitle(String title, DvdMediator dvdMediator) { this.setTitle(title); resetTitle(); this.dvdMediator = dvdMediator; this.dvdMediator.setUpcase(this); } public DvdUpcaseTitle(DvdTitle dvdTitle, DvdMediator dvdMediator) { this(dvdTitle.getTitle(), dvdMediator); } public void resetTitle() { this.setUpcaseTitle(this.getTitle().toUpperCase()); } public void resetTitle(String title) { this.setTitle(title); this.resetTitle(); } public void setSuperTitleUpcase() { this.setTitle(this.getUpcaseTitle()); dvdMediator.changeTitle(this); } public String getUpcaseTitle() { return upcaseTitle; } private void setUpcaseTitle(String upcaseTitle) { this.upcaseTitle = upcaseTitle; } }
download source, use right-click and "Save Target As..." to save with a .java extension.
Test Results
Lowercase LC title :mulholland dr. Lowercase super title :Mulholland Dr. Upcase UC title :MULHOLLAND DR. Upcase super title :Mulholland Dr. After Super set to LC
Lowercase LC title :mulholland dr. Lowercase super title :mulholland dr. Upcase UC title :MULHOLLAND DR. Upcase super title :mulholland dr.
UML
DvdDetails.java - the Originator (the class to be backed up) Contains the inner class DvdMemento - the Memento
//the originator public class DvdDetails { private String titleName; private ArrayList stars; private char encodingRegion; public DvdDetails(String titleName, ArrayList stars, char encodingRegion) { this.setTitleName(titleName); this.setStars(stars); this.setEncodingRegion(encodingRegion); } private void setTitleName(String titleNameIn) { this.titleName = titleNameIn; } private String getTitleName() {
return this.titleName; } private void setStars(ArrayList starsIn) { this.stars = starsIn; } public void addStar(String starIn) { stars.add(starIn); } private ArrayList getStars() { return this.stars; } private static String getStarsString(ArrayList starsIn) { int count = 0; StringBuffer sb = new StringBuffer(); ListIterator starsIterator = starsIn.listIterator(); while (starsIterator.hasNext()) { if (count++ > 0) {sb.append(", ");} sb.append((String) starsIterator.next()); } return sb.toString(); } private void setEncodingRegion(char encodingRegionIn) { this.encodingRegion = encodingRegionIn; } private char getEncodingRegion() { return this.encodingRegion; } public String formatDvdDetails() { return ("DVD: " + this.getTitleName() + ", starring: " + getStarsString(getStars()) + ", encoding region: " + this.getEncodingRegion()); } //sets current state to what DvdMemento has public void setDvdMemento(DvdMemento dvdMementoIn) { dvdMementoIn.getState(); } //save current state of DvdDetails in a DvdMemento public DvdMemento createDvdMemento() { DvdMemento mementoToReturn = new DvdMemento(); mementoToReturn.setState(); return mementoToReturn; } //an inner class for the memento class DvdMemento { private String mementoTitleName; private ArrayList mementoStars;
private char mementoEncodingRegion; //sets DvdMementoData to DvdDetails public void setState() { //Because String are immutable we can just set // the DvdMemento Strings to = the DvdDetail Strings. mementoTitleName = getTitleName(); mementoEncodingRegion = getEncodingRegion(); //However, ArrayLists are not immutable, // so we need to instantiate a new ArrayList. mementoStars = new ArrayList(getStars()); } //resets DvdDetails to DvdMementoData public void getState() { setTitleName(mementoTitleName); setStars(mementoStars); setEncodingRegion(mementoEncodingRegion); } //only useful for testing public String showMemento() { return ("DVD: " + mementoTitleName + ", starring: " + getStarsString(mementoStars) + ", encoding region: " + mementoEncodingRegion); } } }
download source, use right-click and "Save Target As..." to save with a .java extension.
public class TestDvdMemento { public static void main(String[] args) { DvdDetails.DvdMemento dvdMementoCaretaker; //the Caretaker ArrayList stars = new ArrayList(); stars.add(new String("Guy Pearce")); DvdDetails dvdDetails = new DvdDetails("Memento", stars, '1');
dvdMementoCaretaker = dvdDetails.createDvdMemento(); System.out.println("as first instantiated"); System.out.println(dvdDetails.formatDvdDetails()); System.out.println(""); dvdDetails.addStar("edskdzkvdfb"); //oops - Cappuccino on the keyboard! System.out.println("after star added incorrectly"); System.out.println(dvdDetails.formatDvdDetails()); System.out.println(""); System.out.println("the memento"); System.out.println(dvdMementoCaretaker.showMemento()); //show the memento System.out.println(""); dvdDetails.setDvdMemento(dvdMementoCaretaker); //back off changes System.out.println( "after DvdMemento state is restored to DvdDetails"); System.out.println(dvdDetails.formatDvdDetails()); } }
download source, use right-click and "Save Target As..." to save with a .java extension.
Test Results
as first instantiated DVD: Memento, starring: Guy Pearce, encoding region: 1
after title set incorrectly DVD: Memento, starring: Guy Pearce, edskdzkvdfb, encoding region: 1
after DvdMemento state is restored to DvdDetails DVD: Memento, starring: Guy Pearce, encoding region: 1
UML
public class DvdReleaseByCategory { String categoryName; ArrayList subscriberList = new ArrayList(); ArrayList dvdReleaseList = new ArrayList(); public DvdReleaseByCategory(String categoryNameIn) { categoryName = categoryNameIn; } public String getCategoryName() { return this.categoryName; } public boolean addSubscriber(DvdSubscriber dvdSubscriber) { return subscriberList.add(dvdSubscriber); } public boolean removeSubscriber(DvdSubscriber dvdSubscriber) { ListIterator listIterator = subscriberList.listIterator(); while (listIterator.hasNext()) { if (dvdSubscriber == (DvdSubscriber)(listIterator.next())) { listIterator.remove(); return true; } } return false; } public void newDvdRelease(DvdRelease dvdRelease) { dvdReleaseList.add(dvdRelease); notifySubscribersOfNewDvd(dvdRelease); }
public void updateDvd(DvdRelease dvdRelease) { boolean dvdUpdated = false; DvdRelease tempDvdRelease; ListIterator listIterator = dvdReleaseList.listIterator(); while (listIterator.hasNext()) { tempDvdRelease = (DvdRelease)listIterator.next(); if (dvdRelease.getSerialNumber(). equals(tempDvdRelease.getSerialNumber())) { listIterator.remove(); listIterator.add(dvdRelease); dvdUpdated = true; break; } } if (dvdUpdated == true) { notifySubscribersOfUpdate(dvdRelease); } else { this.newDvdRelease(dvdRelease); } } private void notifySubscribersOfNewDvd(DvdRelease dvdRelease) { ListIterator listIterator = subscriberList.listIterator(); while (listIterator.hasNext()) { ((DvdSubscriber)(listIterator.next())). newDvdRelease(dvdRelease, this.getCategoryName()); } }
private void notifySubscribersOfUpdate(DvdRelease dvdRelease) { ListIterator listIterator = subscriberList.listIterator(); while (listIterator.hasNext()) { ((DvdSubscriber)(listIterator.next())). updateDvdRelease(dvdRelease, this.getCategoryName() ); } } }
download source, use right-click and "Save Target As..." to save with a .java extension.
public String getSubscriberName() { return this.subscriberName; } public void newDvdRelease(DvdRelease newDvdRelease, String subscriptionListName) { System.out.println(""); System.out.println("Hello " + this.getSubscriberName() + ", subscriber to the " + subscriptionListName + " DVD release list."); System.out.println("The new Dvd " + newDvdRelease.getDvdName() + " will be released on " + newDvdRelease.getDvdReleaseMonth() + "/" + newDvdRelease.getDvdReleaseDay() + "/" + newDvdRelease.getDvdReleaseYear() + "."); } public void updateDvdRelease(DvdRelease newDvdRelease, String subscriptionListName) { System.out.println(""); System.out.println("Hello " + this.getSubscriberName() + ", subscriber to the " + subscriptionListName + " DVD release list."); System.out.println( "The following DVDs release has been revised: " + newDvdRelease.getDvdName() + " will be released on " + newDvdRelease.getDvdReleaseMonth() + "/" + newDvdRelease.getDvdReleaseDay() + "/" + newDvdRelease.getDvdReleaseYear() + "."); } }
download source, use right-click and "Save Target As..." to save with a .java extension.
public DvdRelease(String serialNumber, String dvdName, int dvdReleaseYear, int dvdReleaseMonth, int dvdReleaseDay) { setSerialNumber(serialNumber); setDvdName(dvdName); setDvdReleaseYear(dvdReleaseYear); setDvdReleaseMonth(dvdReleaseMonth); setDvdReleaseDay(dvdReleaseDay); } public void updateDvdRelease(String serialNumber, String dvdName, int dvdReleaseYear, int dvdReleaseMonth, int dvdReleaseDay) { setSerialNumber(serialNumber); setDvdName(dvdName); setDvdReleaseYear(dvdReleaseYear); setDvdReleaseMonth(dvdReleaseMonth); setDvdReleaseDay(dvdReleaseDay); } public void updateDvdReleaseDate(int dvdReleaseYear, int dvdReleaseMonth, int dvdReleaseDay) { setDvdReleaseYear(dvdReleaseYear); setDvdReleaseMonth(dvdReleaseMonth); setDvdReleaseDay(dvdReleaseDay); } public void setSerialNumber(String serialNumberIn) { this.serialNumber = serialNumberIn; } public String getSerialNumber() { return this.serialNumber; } public void setDvdName(String dvdNameIn) { this.dvdName = dvdNameIn; } public String getDvdName() { return this.dvdName; } public void setDvdReleaseYear(int dvdReleaseYearIn) { this.dvdReleaseYear = dvdReleaseYearIn; } public int getDvdReleaseYear() { return this.dvdReleaseYear;
} public void setDvdReleaseMonth(int dvdReleaseMonthIn) { this.dvdReleaseMonth = dvdReleaseMonthIn; } public int getDvdReleaseMonth() { return this.dvdReleaseMonth; } public void setDvdReleaseDay(int dvdReleaseDayIn) { this.dvdReleaseDay = dvdReleaseDayIn; } public int getDvdReleaseDay() { return this.dvdReleaseDay; } }
download source, use right-click and "Save Target As..." to save with a .java extension.
xfiles.addSubscriber(wrosen); DvdRelease btvsS2 = new DvdRelease("DVDFOXBTVSS20", "Buffy The Vampire Slayer Season 2", 2002, 06, 11); DvdRelease simpS2 = new DvdRelease("DVDFOXSIMPSO2", "The Simpsons Season 2", 2002, 07, 9); DvdRelease soprS2 = new DvdRelease("DVDHBOSOPRAS2", "The Sopranos Season 2", 2001, 11, 6); DvdRelease xfilS5 = new DvdRelease("DVDFOXXFILES5", "The X-Files Season 5", 2002, 04, 1); btvs.newDvdRelease(btvsS2); simpsons.newDvdRelease(simpS2); sopranos.newDvdRelease(soprS2); xfiles.newDvdRelease(xfilS5); xfiles.removeSubscriber(wrosen); xfilS5.updateDvdReleaseDate(2002, 5, 14); xfiles.updateDvd(xfilS5); } }
download source, use right-click and "Save Target As..." to save with a .java extension.
Test Results
Hello Rupert Giles, subscriber to the Buffy the Vampire Slayer DVD release list. The new Dvd Buffy The Vampire Slayer Season 2 will be released on 6/11/2002.
Hello Willow Rosenberg, subscriber to the Buffy the Vampire Slayer DVD release list. The new Dvd Buffy The Vampire Slayer Season 2 will be released on 6/11/2002.
Hello Maggie Simpson, subscriber to the The Simpsons DVD release list.
Hello Junior Soprano, subscriber to the The Sopranos DVD release list. The new Dvd The Sopranos Season 2 will be released on 11/6/2001.
Hello Samantha Mulder, subscriber to the The X-Files DVD release list. The new Dvd The X-Files Season 5 will be released on 4/1/2002.
Hello Willow Rosenberg, subscriber to the The X-Files DVD release list. The new Dvd The X-Files Season 5 will be released on 4/1/2002.
Hello Samantha Mulder, subscriber to the The X-Files DVD release list. The following DVDs release has been revised: The X-Files Season 5 will be released on 5/14/2002.
UML
State Overview
An object appears to change its' class when the class it passes calls through to switches itself for a related class.
public void setDvdStateName(DvdStateName dvdStateNameIn) { this.dvdStateName = dvdStateNameIn; } public void showName(String nameIn) { this.dvdStateName.showName(this, nameIn); } }
download source, use right-click and "Save Target As..." to save with a .java extension.
String nameIn) { System.out.println(nameIn.replace(' ','*')); // show stars twice, switch to exclamation point if (++starCount > 1) { dvdStateContext.setDvdStateName( new DvdStateNameExclaim()); } } }
download source, use right-click and "Save Target As..." to save with a .java extension.
Test Results
Sponge*Bob*Squarepants*-*Nautical*Nonsense*and*Sponge*Buddies Jay*and*Silent*Bob*Strike*Back Buffy!The!Vampire!Slayer!Season!2 The*Sopranos*Season*2
UML
if (dvdName.startsWith("THE ")) { return new String(dvdName.substring(4, (dvdName.length())) + ", THE"); } if (dvdName.startsWith("the ")) { return new String(dvdName.substring(4, (dvdName.length())) + ", the"); } return dvdName; } }
download source, use right-click and "Save Target As..." to save with a .java extension.
public String[] formatDvdNames(String[] namesIn) { return this.formatDvdNames(namesIn, ' '); } public String[] formatDvdNames(String[] namesIn, char replacementIn) { String[] namesOut = new String[namesIn.length]; for (int i = 0; i < namesIn.length; i++) { namesOut[i] = dvdNameStrategy.formatDvdName(namesIn[i], replacementIn); System.out.println( "Dvd name before formatting: " + namesIn[i]); System.out.println( "Dvd name after formatting: " + namesOut[i]); System.out.println("=========================="); } return namesOut; } }
download source, use right-click and "Save Target As..." to save with a .java extension.
String dvdNames[] = new String[3]; dvdNames[0] = "Jay and Silent Bob Strike Back"; dvdNames[1] = "The Fast and the Furious"; dvdNames[2] = "The Others"; char replaceChar = '*'; System.out.println("Testing formatting with all caps"); String[] dvdCapNames = allCapContext.formatDvdNames(dvdNames);
System.out.println(" "); System.out.println( "Testing formatting with beginning the at end"); String[] dvdEndNames = theEndContext.formatDvdNames(dvdNames); System.out.println(" "); System.out.println(" Testing formatting with all spaces replaced with " + replaceChar); String[] dvdSpcNames = spacesContext.formatDvdNames(dvdNames, replaceChar); } }
download source, use right-click and "Save Target As..." to save with a .java extension.
Test Results
Testing formatting with all Dvd name before formatting: Dvd name after formatting: ========================== Dvd name before formatting: Dvd name after formatting: ========================== Dvd name before formatting: Dvd name after formatting: ========================== caps Jay and Silent Bob Strike Back JAY AND SILENT BOB STRIKE BACK The Fast and the Furious THE FAST AND THE FURIOUS The Others THE OTHERS
Testing formatting with beginning the at end Dvd name before formatting: Jay and Silent Bob Strike Back Dvd name after formatting: Jay and Silent Bob Strike Back ========================== Dvd name before formatting: The Fast and the Furious Dvd name after formatting: Fast and the Furious, The ========================== Dvd name before formatting: The Others Dvd name after formatting: Others, The ========================== Testing formatting with all Dvd name before formatting: Dvd name after formatting: ========================== Dvd name before formatting: Dvd name after formatting: ========================== Dvd name before formatting: spaces replaced with * Jay and Silent Bob Strike Back Jay*and*Silent*Bob*Strike*Back The Fast and the Furious The*Fast*and*the*Furious The Others
The*Others
UML
titleInfo.append(this.getTitleBlurb()); titleInfo.append(this.getDvdEncodingRegionInfo()); return titleInfo.toString(); } //the following 2 methods are "concrete abstract class methods" public final void setTitleName(String titleNameIn) { this.titleName = titleNameIn; } public final String getTitleName() { return this.titleName; } //this is a "primitive operation", // and must be overridden in the concrete templates public abstract String getTitleBlurb();
//this is a "hook operation", which may be overridden, //hook operations usually do nothing if not overridden public String getDvdEncodingRegionInfo() { return " "; } }
download source, use right-click and "Save Target As..." to save with a .java extension.
public static void main(String[] args) { TitleInfo bladeRunner = new DvdTitleInfo("Blade Runner", "Harrison Ford", '1'); TitleInfo electricSheep = new BookTitleInfo("Do Androids Dream of Electric Sheep?", "Phillip K. Dick"); TitleInfo sheepRaider = new GameTitleInfo("Sheep Raider"); System.out.println(" "); System.out.println("Testing bladeRunner " + bladeRunner.ProcessTitleInfo()); System.out.println("Testing electricSheep " + electricSheep.ProcessTitleInfo()); System.out.println("Testing sheepRaider " + sheepRaider.ProcessTitleInfo()); } }
download source, use right-click and "Save Target As..." to save with a .java extension.
Test Results
Testing bladeRunner DVD: Blade Runner, starring Harrison Ford, encoding region: 1 Testing electricSheep Book: Do Androids Dream of Electric Sheep?, Author: Phillip K. Dick Testing sheepRaider Game: Sheep Raider
UML
public class TitleShortBlurbVisitor extends TitleBlurbVisitor { public void visit(BookInfo bookInfo) { this.setTitleBlurb("SB-Book: " + bookInfo.getTitleName()); } public void visit(DvdInfo dvdInfo) { this.setTitleBlurb("SB-DVD: " + dvdInfo.getTitleName()); } public void visit(GameInfo gameInfo) { this.setTitleBlurb("SB-Game: " + gameInfo.getTitleName()); } }
download source, use right-click and "Save Target As..." to save with a .java extension.
Test Results
Long Blurbs:
Testing bladeRunner LB-DVD: Blade Runner, starring Harrison Ford, encoding region: 1 Testing electricSheep LB-Book: Do Androids Dream of Electric Sheep?, Author: Phillip K. Dick Testing sheepRaider LB-Game: Sheep Raider
Short Blurbs: Testing bladeRunner SB-DVD: Blade Runner Testing electricSheep SB-Book: Do Androids Dream of Electric Sheep? Testing sheepRaider SB-Game: Sheep Raider
UML