Last week, we looked at the Null Object pattern. Remember that this pattern was not documented in the GoF book (horrors!). Remember too that there are many useful and commonly used patterns that are also not included in it. They are no less valid than the GoF patterns.
This week we’ll be looking at another non-GoF pattern, the Simple Factory pattern. This is the easiest factory pattern to understand, and arguably the most commonly used. The simple factory can probably be seen as a design principle rather than a design pattern.
The GoF book includes the Abstract Factory pattern and the Factory Method pattern, both of which we’ll cover later. In contrast to either of these patterns, the Simple Factory is made up of just one concrete factory which doesn’t inherit from another abstraction layer.
Once we understand how the simple factory works, then it will be easier to understand both the factory method and the abstract factory.
The Simple Factory Pattern
The simple factory pattern is a creational pattern that creates objects without exposing the instantiation logic to the client. It encapsulates the object creation code, but keeps control over how the object is created. A simple factory is often implemented as a class with a static method that returns the object requested. This is sometimes referred to as a static factory. We use a common interface to refer to the newly created object.
The implementation is simple:
- The client needs an object, but rather than creating it with the
new
operator, it asks the factory for a new object, providing information about the type of object it requires. - The factory instantiates a new concrete object and then returns it to the client.
- The client uses the object as an abstract type without being aware about its concrete implementation.
Simple Factory Pattern: Example Code
We’re still hard at work on our first person shooter game. We need assorted monsters and other fearsome creatures to hunt the players, who in turn will be hunted by them.
At startup and possibly at various times during the game, we need to create these creatures and unleash them on the hapless players. The question arises: should we call the constructors directly, or should we encapsulate them for ease of use? It would be better to encapsulate them, because then we could create objects without exposing any of the instantiation logic to the rest of the game.
We would first create an abstract base class defining a common interface for our creatures. Here we’ll just define that they can move, hunt and kill.
public abstract class Creature { public abstract void move(); public abstract void hunt(); public abstract void kill(); }
We would have a number of concrete classes extending this base class:
public class Zombie extends Creature { @Override public void move() { /* appropriate code */ } @Override public void hunt() { /* appropriate code */ } @Override public void kill() { /* appropriate code */ } } public class Werewolf extends Creature { @Override public void move() { /* appropriate code */ } @Override public void hunt() { /* appropriate code */ } @Override public void kill() { /* appropriate code */ } } public class Vampire extends Creature { @Override public void move() { /* appropriate code */ } @Override public void hunt() { /* appropriate code */ } @Override public void kill() { /* appropriate code */ } }
We can define an enum
specifying the CreatureType
. This will be used to select which creature the factory creates. The enum
could be inside or outside the factory class.
public enum CreatureType { VAMPIRE, WEREWOLF, ZOMBIE; }
We would encapsulate the constructors for the concrete classes inside the factory class as follows:
public class CreatureFactory { // static factory method public static Creature create(CreatureType type) { switch (type) { case VAMPIRE: return new Vampire(); case WEREWOLF: return new Werewolf(); case ZOMBIE: return new Zombie(); default: return null; } } } // end of class
The create()
factory method encapsulates the selection and instantiation of creatures, and isolates the rest of the game from repetitive code. We’ve made the create()
method static
for convenience; this is not a requirement of the pattern, but is usually done. We’ve simply called the default constructors here, but obviously we could execute any number of statements to instantiate and initialise the creatures appropriately.
It’s not shown here, but the factory class is often created as a singleton.
Whenever we need a creature of a specific type, we ask the factory to create it for us:
// Create a Werewolf Creature creature1 = CreatureFactory.create(CreatureType.WEREWOLF); creature1.hunt(); // Create a Zombie Creature creature2 = CreatureFactory.create(CreatureType.ZOMBIE); creature2.hunt();
Obviously the factory code is not production quality. We should have a better default
clause for the switch
statement. We could even use the Null Object pattern to return a NullCreature
in the default
clause. When we add new creatures we will have to modify and retest the factory class. This is inflexible and violates the Open-closed principle (a class should be open for extension, but closed for modification). To avoid this, we could use the Reflection API to register new creatures on the fly with the factory.
Simple Factory Pattern in the Java API
There are a number of methods in the standard JSE API that use the simple factory pattern. Some examples follow:
- The overloaded
getInstance()
methods ofjava.util.Calendar
. - The overloaded
getBundle()
methods ofjava.util.ResourceBundle
. - The
getInstance()
and similar methods ofjava.text.NumberFormat
. - The
forName()
method injava.nio.charset.Charset
. - The
createMarshaller()
,createUnmarshaller()
and similar methods injavax.xml.bind.JAXBContext
.
The Spring framework uses the simple factory pattern as the core of the BeanFactory
classes. The overloaded (non-static) getBean()
methods return an object that has been created by the factory during startup. We can request beans (objects) by name and/or type (either abstract or concrete).
What’s Next?
Next week we’ll leverage off what we learned this week, and we’ll look at one of the related GoF factory patterns, the Factory Method pattern. Stay tuned!
As always, please share your comments. I enjoy your opinions, and they help me to write better tips.