Factory Method Pattern

Factory Method Pattern provides a way of encapsulating object creation.
The definition by Gang of Four:

Define an interface for creating an object, but let subclasses decide which class to instantiate. The Factory method lets a class defer instantiation it uses to subclasses.

I will first walk through some examples of factory method pattern, and then compare it to the simple factory pattern, hoping that it will give you a better understand of factory method pattern.

A simple example

As shown in the UML below, the interface Factory defines a method for creating an object, but only its subclasses can create an object and can decide which class to instantiate.

This simple example can only give you a basic idea of factory method pattern. From my point of view, I have no idea why I need such a complex hierarchy, and why I need to defer the object creation to different factories, and how I can control which factory to use. So let’s learn from some real examples.

More examples

i. Java API: commons-logging

It is a libary that provides a way of logging and allows developers to plug in a specific logging implementation.
It has an interface Log which abstracts logging APIs, and an abstract class LogFactory which creates instances of Log. This is how it is used:

1
private Log log = LogFactory.getLog(ThisIsAClass.class);

The implementation of getLog(Class) is as below. LogFactory itself doesn’t create the Log instances because it doesn’t implement the method getInstance(), it defers the object creation to its subclasses, like LogFactoryImpl.

1
2
3
public static Log getLog(Class clazz) throws LogConfigurationException {
return (getFactory().getInstance(clazz));
}

Here comes the question: why LogFactory defers the object creation to its subclasses?
If LogFactory implements the object creation, and if someone who uses this library wants a different implementation of creating objects, he has to modify LogFactory and rebuild the library. This is silly and totally violates the principal of “open to extension but close to modification”. A good practice is to have the subclasses decide how to create objects. Anyone who wants to plug in a new logging implementation can achieve this by extending LogFactory and implementing the method getInstance().
As shown in the following UML, I can define a new class MyLogFactoryImpl which extends LogFactory, and I can decide to create the objects of Log4JLogger or MyLogger in my class.

And the next question is: how I can control which factory to use at the runtime? This can be done by passing parameters or using configuration files.

ii. Java API: javax.xml.parsers

It provides different ways to parse XML documents, such as DOM and SAX parser. It adopts factory method pattern to create objects of SAXParser, and the same for DocumentBuilder. Take SAXParser for example,

SAXParserFactory is an abstract class. It implements the method newInstance() to instantiate SAXParserFactory, which allows the clients to implement their own factory. And it defers the creation of SAXParser objects to its subclasses, like SAXParserFactoryImpl, which allows the clients to user their own factory to create their own SAX parser.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public abstract class SAXParserFactory {
public static SAXParserFactory newInstance() {
return FactoryFinder.find(
/* The default property name according to the JAXP spec */
SAXParserFactory.class,
/* The fallback implementation class name */
"com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl");
}
public static SAXParserFactory newInstance(String factoryClassName, ClassLoader classLoader){
//do not fallback if given classloader can't find the class, throw exception
return FactoryFinder.newInstance(SAXParserFactory.class,
factoryClassName, classLoader, false);
}

public abstract SAXParser newSAXParser() throws ParserConfigurationException, SAXException;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class SAXParserFactoryImpl extends SAXParserFactory {
private SAXParserImpl newSAXParserImpl() throws ParserConfigurationException, SAXNotRecognizedException, SAXNotSupportedException {
SAXParserImpl saxParserImpl;
try {
saxParserImpl = new SAXParserImpl(this, features);
} catch (SAXNotSupportedException e) {
throw e;
} catch (SAXNotRecognizedException e) {
throw e;
} catch (SAXException se) {
throw new ParserConfigurationException(se.getMessage());
}
return saxParserImpl;
}
}

P.S. Simple Factory Pattern

Someone argues that Simple Factory Pattern is not a design pattern, but a simple encapsulation of object creation. By wrapping the code of creating new objects in a new class, it decouples the creation and the use of an object.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public interface Song {
// ...
}
public class Indie implements Song {
// ...
}
public class Rock implements Song {
// ...
}

public class SimpleFactory {
public static Song createSong(int type) {
Song obj = null;
switch (type) {
case 1: obj = new Indie(); break;
case 2: obj = new Rock(); break;
}
return obj;
}
}

public class Client {
public static void main(String[] args) {
Song obj = SimpleFactory.createSong(1);
}
}

Pros:

  • Hide the complex logic of creating objects
  • Changes to the logic of creating objects won’t require changes to the client code
  • Code can be reused if the object creation is required in many places

i. Factory Method Pattern vs. Simple Factory Pattern

Simple factory is just an encapsulation of a piece of code so that it can be reused. It provides only one way of creating objects, and hence if you want to create objects in other ways, you have to modify the factory itself, but which is the strength of factory method pattern. But of course, it doesn’t mean you must use factory method pattern, it all depends on how you want the factory to be used.

ii. An example: java.util.Calendar.getInstance()

Some say that Calendar.getInstance() is an example of adopting factory method pattern, but in my opinion, the Calendar class just provides a simple built-in factory method, which is not the same as the factory method pattern. I would argue that it is more like a simple factory.
Let’s look at the code first.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public abstract class Calendar {
protected Calendar() { // ... }

public static Calendar getInstance() {
return createCalendar(TimeZone.getDefault(), Locale.getDefault(Locale.Category.FORMAT));
}

private static Calendar createCalendar(TimeZone zone, Locale aLocale) {
// ...
Calendar cal = null;
if (aLocale.getLanguage() == "th" && aLocale.getCountry() == "TH") {
cal = new BuddhistCalendar(zone, aLocale); // subclass of Calendar
} else if (aLocale.getVariant() == "JP" && aLocale.getLanguage() == "ja" & aLocale.getCountry() == "JP") {
cal = new JapaneseImperialCalendar(zone, aLocale); // subclass of Calendar
} else {
cal = new GregorianCalendar(zone, aLocale); // subclass of Calendar
}
return cal;
}
}

1
2
Calendar cal = Calendar.getInstance();
System.out.println(cal.getTime());

Calendar is an abstract class, and it is extened by BuddhistCalendar, JapaneseImperialCalendar and GregorianCalendar. Calendar cannot be instantiated, but it provides the method getInstance() for creating objects which hides the complexity of choosing which class to instantiate. However, it does not use factory method pattern for the following reasons:

  1. It does not defer the object creation to its subclasses
  2. It’s impossible for the client to create other types of calendar by extending the Calendar class

Summary

Factory method pattern provides a flexible way of object creation. It not only encapsulates the instantiation of objects, but lets the subclasses of the factory decides which class to instantiate, so that the client code can have its own factory implementation to create specific objects.

References

1 Wikipedia: Factory Method Pattern
2 Factory Patterns
3 Examples of Design Patterns in Java Core Libraries