Last week, we looked at the (non-GoF) Simple Factory pattern. This was a simple factory consisting of just one concrete class with a static factory method. It didn’t inherit from any other abstraction layer. Now that we know how the simple factory works, it will be easier to understand the GoF factory patterns.
This week we’ll be looking at the first of the related GoF factory patterns, the Factory Method pattern (also known as Virtual Constructor).
The Factory Method Pattern
The Gang of Four book defines the Factory Method pattern as follows:
“Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.”.
The factory method is a creational pattern that delegates the responsibility of object creation to helper subclasses. The factory method defines an interface for creating an object, but leaves the choice of its type to the subclasses, with the creation being deferred to run-time.
We use the factory method if the business requirements require more than just object creation. If we want to control or customise all of the creation steps, then we use the factory method. If we want to control an algorithm/strategy of a family of objects, we can think about using the factory method pattern. It works well with the template pattern, where a template method controls the algorithm steps for the creation of the subclasses.
The factory method must be used for a family of objects. If the classes don’t extend a common interface or base class then they cannot be used in a factory method.
We use the factory method when:
- A class cannot anticipate the type of the objects it must create.
- A class wants its subclasses to specify the type of a newly created object.
The Factory Method Pattern: Example Code
Remember that we need to create creatures for our first person shooter game and let them loose to hunt and be hunted by the players.
We already have a hierarchy of classes defining our creatures. The abstract base class follows (some of the code has been refactored since the last version):
public abstract class Creature { public enum Speed {SLOW, MEDIUM, FAST}; public enum Movement {SHUFFLE, RUN, FLY}; public enum Strength {WEAK, NORMAL, POWERFUL}; // instance fields private Speed speed; private Movement movement; private Strength strength; // abstract methods to be implemented by subclasses public abstract void move(); public abstract void hunt(); public abstract void kill(); // constructors and accessor methods not shown } // end of class
We also have a number of concrete classes extending this base class:
public class Zombie extends Creature { /* appropriate code */ } public class Werewolf extends Creature { /* appropriate code */ } public class Vampire extends Creature { /* appropriate code */ }
Last week, we created a simple factory to hide the details of the creation process. Let’s convert that simple factory into a factory method.
Remember that in the simple factory, we passed a CreatureType
as a parameter to specify what creature we wanted, such as a Werewolf
or Zombie
, and the simple factory hid the instantiation details from us.
public enum CreatureType { VAMPIRE, WEREWOLF, ZOMBIE; }
However, in the factory method pattern, we could code it with or without parameters to specify the type needed. In both cases, the subclasses would decide what object to create.
If we use parameters, they don’t necessarily have specify the exact creature type we want as we did with the simple factory. It gives us a more flexible design if we pass in the characteristics of the creature we want. The factory subclass then decides which creature meets those characteristics, and creates a Creature
object from a specific concrete Creature
subclass. We don’t know what specific subtype of Creature
it will be; all we know is that it will be a Creature
.
The factory method pattern defines an abstract factory class that has an abstract method to instantiate the object (a Creature
in our game). Concrete subclasses of the factory make the decision as to what specific subclass of Creature
to create. Having separate factory subclasses make our code more flexible.
We will create an abstract CreatureFactory
class which will only have one concrete subclass ConcreteCreatureFactory
. With a more extensive hierarchy of classes, such as Monster
and Beast
superclasses with subclasses of Dragon
, Ogre
, Orc
, Troll
, Goblin
, Elf
, etc., the benefits of the factory method pattern will be more apparent. We could then have a ConcreteMonsterFactory
and a ConcreteBeastFactory
, etc.
We would code the abstract CreatureFactory
as follows:
public abstract class CreatureFactory { public Creature build(Creature.Movement movement, Creature.Speed speed, Creature.Strength strength) { Creature creature = selectCreature(movement, speed); // we can call setters here or in the selectCreature() method creature.setStrength(strength); return creature; } // Abstract factory method to be implemented by the subclasses protected abstract Creature selectCreature(Creature.Movement movement, Creature.Speed speed); } // end of class
The CreatureFactory
class contains the public method build()
that takes the speed, movement and strength characteristics as parameters. The build()
method calls the selectCreature()
method, which is the actual factory method after which the pattern is named.
The implementation of selectCreature()
is delegated to the subclasses so that each subclass determines the specific type of creature to instantiate. The method is protected
because we only want subclasses to use it. It is not intended to be invoked by clients.
Here is the ConcreteCreatureFactory
subclass:
public class ConcreteCreatureFactory extends CreatureFactory { protected Creature selectCreature(Creature.Movement movement, Creature.Speed speed) { if (movement == Creature.Movement.SHUFFLE) { return new Zombie(speed); } else if (movement == Creature.Movement.RUN) { return new Werewolf(speed); } else { return new Vampire(speed); } } } // end of class
Whenever we need a creature with specific characteristics, possibly for a hand-to-hand duel in our game, we ask the factory to create it for us:
// Creating the concrete factory CreatureFactory factory = new ConcreteCreatureFactory(); // Create a fast, powerful, flying creature Creature creature1 = factory.build(Creature.Movement.FLY, Creature.Speed.FAST, Creature.Strength.POWERFUL); creature1.hunt(); // Create a slow, weak, shuffling creature Creature creature2 = factory.build(Creature.Movement.SHUFFLE, Creature.Speed.SLOW, Creature.Strength.WEAK); creature2.hunt();
Summary
In both the simple factory and the factory method, we pass in a parameter that identifies the object instance we want. The factory method subclass uses that parameter to decide which concrete class best meets those characteristics, while the simple factory merely hides the instantiation details from us.
The factory method is the most well known factory pattern, largely because it was documented in the GoF book. It is essentially just a specialised case of the simple factory pattern. In modern APIs, the simple factory pattern with class registration is used more often.
When we design an application, we must consider whether we really need a factory to create objects. Using a factory adds complexity to our application, which may not be necessary. If we have many objects of the same base type and we use them through their abstract base class, then we probably need a factory; otherwise probably not.
What’s next?
In the weeks ahead, we’ll continue examining some of the more useful design patterns. Stay tuned!
As always, please share your comments and questions.