Java Design Patterns .

Java Design Patterns Abstract Factory

Abstract Factory (AKA Kit) Overview

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();
    }
}
To download source right-click here and "Save As...".

BostonConcreteSoupFactory.java - One of Two concrete factories extending the abstract factory

class BostonConcreteSoupFactory extends AbstractSoupFactory {
    public BostonConcreteSoupFactory() {
        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"); } }
To download source right-click here and "Save As...".

HonoluluConcreteSoupFactory.java - Two of Two concrete factories extending the abstract factory

class HonoluluConcreteSoupFactory extends AbstractSoupFactory {
    public HonoluluConcreteSoupFactory() {
        factoryLocation = "Honolulu";
    }
    public ClamChowder makeClamChowder() {
       return new HonoluluClamChowder();
    }
    public FishChowder makeFishChowder() {
       return new HonoluluFishChowder();
    }
}

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"); } }
To download source right-click here and "Save As...".

Soup.java - A helper class

import java.util.ArrayList;
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"); } }
To download source right-click here and "Save As...".

TestAbstractSoupFactory.java - Testing the abstract factory

import java.util.Calendar;

class TestAbstractSoupFactory { public static Soup MakeSoupOfTheDay(AbstractSoupFactory concreteSoupFactory) { Calendar todayCalendar = Calendar.getInstance(); //int dayOfWeek = todayCalendar.get(Calendar.DAY_OF_WEEK); int dayOfWeek = Calendar.TUESDAY; if (dayOfWeek == Calendar.MONDAY) { return concreteSoupFactory.makeChickenSoup(); } else if (dayOfWeek == Calendar.TUESDAY) { return concreteSoupFactory.makeClamChowder(); } else if (dayOfWeek == Calendar.WEDNESDAY) { return concreteSoupFactory.makeFishChowder(); } else if (dayOfWeek == Calendar.THURSDAY) { return concreteSoupFactory.makeMinnestrone(); } else if (dayOfWeek == Calendar.FRIDAY) { return concreteSoupFactory.makePastaFazul(); } else if (dayOfWeek == Calendar.SATURDAY) { return concreteSoupFactory.makeTofuSoup(); } else { return concreteSoupFactory.makeVegetableSoup(); } }

public static void main(String[] args) { AbstractSoupFactory concreteSoupFactory = new BostonConcreteSoupFactory(); 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()); } }
To download source right-click here and "Save As...".

Test Results (if run on a Tuesday)

The Soup of the day in Boston is QuahogChowder
The Soup of the day in Honolulu is PacificClamChowder

UML

UML for Abstract Factory

References

online

Portland Pattern Repository

Books

Design Patterns by Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides

Java Design Patterns - A Tutorial by James W. Cooper
Comments Comments are left by visitors to FluffyCat.com and may or may not be accurate.
Comment by Larry on 2014-06-27 Rate this Comment

I added the soup class to help make this clearer. It was in some of the other examples, but somehow never got added to Abstract Factory.

Perhaps Boris is correct, for the Abstract Factory example I probably could have left it at just the two soups. I have seven because the MakeSoupOfTheDay() depends on the day of the week, and there are seven days. But, I could have had one soup for three days and the other soup for four days. There did not really need to be seven different soups.

Comment by Anonymous on 2013-01-31 Rate this Comment

All the "Soups" should implement an interface by that name. The interface should enforce general methods for the implementing classes eg (getSoupName, getSoupType (hot/cold) etc.

Comment by aydaroos on 2012-03-30 Rate this Comment

Great explanation and I agree with Boris, Congrat

Comment by vnraju on 2012-03-30 Rate this Comment

Abstract Factory design pattern explanation is not enough,It would be better if you explain little bit more and clear.
The above example missing the below listed classes :
1.ChickenSoup , 2. ClamChowder 3. FishChowder 4. Minnestrone
5. PastaFazul , 6. TofuSoup
and finally 7. Soup
Soup class is the super class for all the 1 to 6 classes and it must implement the method getSoupName() defined in the Soup class.
Implementation of the Soup Class :
public class Soup {
public String getSoupName(){
return "Soup";
}
}

Comment by vnraju on 2013-05-24 Rate this Comment

Abstract Factory design pattern explanation is not enough,It would be better if you little bit more.
The above example missing the below listed classes :
1.ChickenSoup , 2. ClamChowder 3. FishChowder 4. Minnestrone
5. PastaFazul , 6. TofuSoup
and finally 7. Soup
Soup class is the super class for all the 1 to 6 classes and it must implement the method getSoupName() defined in the Soup class.
Implementation of the Soup Class :
public class Soup {
public String getSoupName(){
return "Soup";
}
}


Comment by ayer on 2012-03-30 Rate this Comment

this is great, but...did I mis something? I couldn't find the definitions for FishChowder and ClamChowder classes...

Comment by archive on 2013-05-15 Rate this Comment

I realy appreciate the Java Patterns on your site.
Since I like to play with the examples I simply
copied it into text fils and compiled them.
I found a few minor problems you may want to know
about:

Abstract Factory
================
- declaration of dayOfWeek was commented out:
//int dayOfWeek =
todayCalendar.get(Calendar.DAY_OF_WEEK);

Comment by Sunny on 2008-06-12 Rate this Comment

Thanks for your efforts.
I believe soup.java should be add to this page to make this example completed.

 
Sign in to comment on Java Design Patterns Abstract Factory.