The factory method pattern

In the simplest terms, a factory method is a method which creates objects and lets a class defer instantiation to its subclasses.

It may either be implemented directly in a class (and optionally overriden in its children) or specified in an interface (and implemented by classes which use it).

It helps decouple code from concrete implementations of interfaces, making it more flexible to change and solves problems related to deferring class instantiation, giving subclasses the ability to define the way an object is created.

Usage example – subclassing

You have two types of Weapons Lasers and Rockets:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
interface Weapon {
String shoot();
}
class Laser implements Weapon {
@Override public String shoot() {
return "lasers!";
}
}
class Rocket implements Weapon {
@Override public String shoot() {
return "rockets!";
}
}
interface Weapon { String shoot(); } class Laser implements Weapon { @Override public String shoot() { return "lasers!"; } } class Rocket implements Weapon { @Override public String shoot() { return "rockets!"; } }
interface Weapon {
    String shoot();
}
class Laser implements Weapon {
    @Override public String shoot() {
        return "lasers!";
    }
}
class Rocket implements Weapon {
    @Override public String shoot() {
        return "rockets!";
    }
}

You want to create two types of spaceships – a Frigate (equipped with Lasers) and a Destroyer (equipped with Rockets), so that you can make them shoot their weapons:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
abstract class Spaceship {
abstract protected Weapon createWeapon();
public String shootWeapon() {
Weapon Weapon = createWeapon();
return "Firing my ".concat(Weapon.shoot());
}
}
class Frigate extends Spaceship {
@Override protected Weapon createWeapon() {
return new Laser();
}
}
class Destroyer extends Spaceship {
@Override protected Weapon createWeapon() {
return new Rocket();
}
}
abstract class Spaceship { abstract protected Weapon createWeapon(); public String shootWeapon() { Weapon Weapon = createWeapon(); return "Firing my ".concat(Weapon.shoot()); } } class Frigate extends Spaceship { @Override protected Weapon createWeapon() { return new Laser(); } } class Destroyer extends Spaceship { @Override protected Weapon createWeapon() { return new Rocket(); } }
abstract class Spaceship {
    abstract protected Weapon createWeapon();
    public String shootWeapon() {
        Weapon Weapon = createWeapon();
        return "Firing my ".concat(Weapon.shoot());
    }
}
class Frigate extends Spaceship {
    @Override protected Weapon createWeapon() {
        return new Laser();
    }
}
class Destroyer extends Spaceship {
    @Override protected Weapon createWeapon() {
        return new Rocket();
    }
}

That abstract

createWeapon()
createWeapon() function is the factory method. It creates an instance of a class implementing the
Weapon
Weapon interface – the choice of the class is up to the subclasses extending the
Spaceship
Spaceship class.

Finally, we can interact with the

Spaceships
Spaceships:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
class SpaceWarExample {
public static void main(String[] args) {
Spaceship Frigate = new Frigate();
System.out.println(Frigate.shootWeapon());
Spaceship Destroyer = new Destroyer();
System.out.println(Destroyer.shootWeapon());
}
}
class SpaceWarExample { public static void main(String[] args) { Spaceship Frigate = new Frigate(); System.out.println(Frigate.shootWeapon()); Spaceship Destroyer = new Destroyer(); System.out.println(Destroyer.shootWeapon()); } }
class SpaceWarExample {
    public static void main(String[] args) {
        Spaceship Frigate = new Frigate();
        System.out.println(Frigate.shootWeapon());
        Spaceship Destroyer = new Destroyer();
        System.out.println(Destroyer.shootWeapon());
    }
}

…Which gives us the output:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
Firing my lasers!
Firing my rockets!
Firing my lasers! Firing my rockets!
Firing my lasers!
Firing my rockets!

Usage example – using factory classes

It is possible to take the factory method one step further and extract the method into its own factory class. Imagine that you have two types of Spears Light Spears and Heavy Spears:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
interface Spear {
String throwAtNearestEnemy();
}
class HeavySpear implements Spear {
@Override public String throwAtNearestEnemy() {
return "Throwing a heavy spear...";
}
}
class LightSpear implements Spear {
@Override public String throwAtNearestEnemy() {
return "Throwing a light spear...";
}
}
interface Spear { String throwAtNearestEnemy(); } class HeavySpear implements Spear { @Override public String throwAtNearestEnemy() { return "Throwing a heavy spear..."; } } class LightSpear implements Spear { @Override public String throwAtNearestEnemy() { return "Throwing a light spear..."; } }
interface Spear {
    String throwAtNearestEnemy();
}
class HeavySpear implements Spear {
    @Override public String throwAtNearestEnemy() {
        return "Throwing a heavy spear...";
    }
}
class LightSpear implements Spear {
    @Override public String throwAtNearestEnemy() {
        return "Throwing a light spear...";
    }
}

You want to have a Spear Thrower that will be able to throw both a Heavy Spear and a Light Spear at the nearest enemy. To achieve that, you can create factory classes for the

Spears
Spears:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
interface SpearFactory {
Spear createSpear();
}
class HeavySpearFactory implements SpearFactory {
@Override public Spear createSpear() {
return new HeavySpear();
}
}
class LightSpearFactory implements SpearFactory {
@Override public Spear createSpear() {
return new LightSpear();
}
}
interface SpearFactory { Spear createSpear(); } class HeavySpearFactory implements SpearFactory { @Override public Spear createSpear() { return new HeavySpear(); } } class LightSpearFactory implements SpearFactory { @Override public Spear createSpear() { return new LightSpear(); } }
interface SpearFactory {
    Spear createSpear();
}

class HeavySpearFactory implements SpearFactory {
    @Override public Spear createSpear() {
        return new HeavySpear();
    }
}

class LightSpearFactory implements SpearFactory {
    @Override public Spear createSpear() {
        return new LightSpear();
    }
}

These factories are the key to this implementation of the factory method pattern. Notice that the factories’ sole purpose is creating

Spears
Spears. You can now define a
SpearThrower
SpearThrower:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
class SpearThrower {
public String useSpear(SpearFactory SpearFactory) {
final Spear spear = SpearFactory.createSpear();
return spear.throwAtNearestEnemy();
}
}
class SpearThrower { public String useSpear(SpearFactory SpearFactory) { final Spear spear = SpearFactory.createSpear(); return spear.throwAtNearestEnemy(); } }
class SpearThrower {
    public String useSpear(SpearFactory SpearFactory) {
        final Spear spear = SpearFactory.createSpear();
        return spear.throwAtNearestEnemy();
    }
}

The

SpearThrower
SpearThrower is independent of the 
Spears
Spears he uses. Each time you want him to use a
Spear
Spear, you pass a
SpearFactory
SpearFactory to his 
useSpear()
useSpear() function, which then provides the relevant
Spear
Spear. Another option would be to pass a 
SpearFactory
SpearFactory in the 
SpearThrower's
SpearThrower's constructor.

We can now use the 

SpearThrower
SpearThrower in our application:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
class SpearThrowerExample {
public static void main(String[] args) {
SpearThrower spearThrower = new SpearThrower();
System.out.println(spearThrower.useSpear(new HeavySpearFactory());
System.out.println(spearThrower.useSpear(new LightSpearFactory()));
}
}
class SpearThrowerExample { public static void main(String[] args) { SpearThrower spearThrower = new SpearThrower(); System.out.println(spearThrower.useSpear(new HeavySpearFactory()); System.out.println(spearThrower.useSpear(new LightSpearFactory())); } }
class SpearThrowerExample {
    public static void main(String[] args) {
        SpearThrower spearThrower = new SpearThrower();
        System.out.println(spearThrower.useSpear(new HeavySpearFactory());
        System.out.println(spearThrower.useSpear(new LightSpearFactory()));
    }
}

The code above will output:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
Throwing a heavy spear...
Throwing a light spear...
Throwing a heavy spear... Throwing a light spear...
Throwing a heavy spear...
Throwing a light spear...

You can then add more types of

Spears
Spears (e.g. a Weightless Spear) and the
SpearThrower
SpearThrower will be able to use them right away – there will be no need of modifying the
SpearThrower's
SpearThrower's code. Let’s imagine someone wrote a library called
ExtendedSpearTypes
ExtendedSpearTypes, which contains a 
WeightlessSpear
WeightlessSpear and a
WeightlessSpearFactory
WeightlessSpearFactory. We can include the library in our application and make a call like so, without making major changes to our core code:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
spearThrower.useSpear(new WeightlessSpearFactory())
spearThrower.useSpear(new WeightlessSpearFactory())
spearThrower.useSpear(new WeightlessSpearFactory())

This way, the coupling exists on such a low level of abstraction that adding or removing new Spear type logic is trivial.

Notice, also, that this implementation is just one step away of becoming the Abstract Factory pattern – a pattern which could be described as a factory of factories. Both of them utilize the concept of a Factory class, the difference being that here our factory class only produces one instance of a desired interface implementation, instead of many related instances.

Daniel Frąk Written by:

Be First to Comment

Leave a Reply

Your email address will not be published. Required fields are marked *