Factory Pattern — A Quick Guide

Design Patterns: Factory Pattern

Emre Tanrıverdi
4 min readMay 16, 2021

There are 3 types of Factory Pattern: Simple, Method and Abstract.

Photo by Natalie Kuhl on Unsplash

Simple Factory

Suppose you have a local pizza shop and you instantiate a pizza object for every order you get.

Pizza pizza = new Pizza();

Instead of that, you can simply do this:

public class Pizza {
private Pizza(){} // hide the constructor, so no one
initializes pizza with "new"
public static Pizza create() {
return new Pizza();
}
}

or this:

public class PizzaFactory {
public static Pizza create() {
return new Pizza();
}
}
public class Pizza {

// assuming your models are in the same package, you can
make this package-private to make sure constructor won't be
called from client code
protected Pizza(){}
}

and the client code will be like this:

Pizza pizza = Pizza.create();orPizza pizza = PizzaFactory.create();

If you’d like to change how this method works (or maybe add some business logic to it), you can update create instead of putting the logic code to the constructor.

Don’t fret, I hear you, you say we could achieve the same thing with a constructor.
Well, Simple Factory is basically a constructor that has a custom name.

Think of it like this:

Person person = new Person(170);toPerson person = Person.fromHeight(170);orPerson person = PersonFactory.fromHeight(170);

It’s up to you to use it or not. I personally like it.

Some people don’t even count Simple Factory as a Design Pattern, though.
Factory Method and Abstract Factory on the other hand, is a bit different.

So let’s get to Factory Method.

Factory Method

So… back to the order management system.

Let’s say your business is larger now and you start to sell burgers.

Factory Method helps you to select between pizza and burger by overriding a method but keeps non-varying parts in a common method.

Let’s first create a Meal interface with meals implementing it.

public interface Meal {
// implementations
}
public class Pizza implements Meal {
// implementations
}
public class Burger implements Meal {
// implementations
}

Let’s make a more generic MealFactory interface with both PizzaFactory and BurgerFactory implementing it.

interface MealFactory {
//factory method
Meal create(); // compulsory inheritance
}
public class PizzaFactory implements MealFactory {
// implementations
@Override
Meal create() {
return new Pizza();
}
}
public class BurgerFactory implements MealFactory {
// implementations

@Override
Meal create() {
return new Burger();
}
}

Both pizza types override create according their own needs.

Now client code would be like:

MealFactory pizzaFactory = new PizzaFactory();
Meal pizza = pizzaFactory.create();
MealFactory burgerFactory = new BurgerFactory();
Meal burger = burgerFactory.create();

That’s it!

If both Meals have a common method regardless of their type, you can turn MealFactory to abstract class instead of an interface.

abstract class MealFactory {
//factory method
protected abstact Meal create(); // compulsory inheritance
public void createAndSendOrder() {
Meal meal = create();
// do stuff
}
}
public class PizzaFactory extends MealFactory {
// implementations
@Override
protected Meal create() {
return new Pizza();
}
}
public class BurgerFactory extends MealFactory {
// implementations

@Override
protected Meal create() {
return new Burger();
}
}

And the client code would be like:

MealFactory pizzaFactory = new PizzaFactory();
pizzaFactory.createAndSendOrder();
MealFactory burgerFactory = new BurgerFactory();
burgerFactory.createAndSendOrder();

It’s great because I also encapsulated the creation logic from client completely.

Abstract Factory

Now let’s add vegan options of pizza and burger.

So it will be like:

interface MealFactory {
Pizza createPizza(); // no inheritance needed
Burger createBurger(); // no inheritance needed
}
public class VeganMealFactory implements MealFactory { @Override
public Pizza createPizza() {
return new VeganPizza();
}
@Override
public Burger createBurger() {
return new VeganBurger();
}
}
public class NonVeganMealFactory implements MealFactory { @Override
public Pizza createPizza() {
return new NonVeganPizza();
}
@Override
public Burger createBurger() {
return new NonVeganBurger();
}
}

Now it’s a factory of factories.

In Factory Method, only a single method was responsible of creation of a pizza, here we have separate methods for separate pizzas, so whole class is responsible.

In Factory Method,Pizza and Burger needed to be in type Meal,
here it’s not compulsory.

Let’s see the client code:

MealFactory veganMealFactory = new VeganMealFactory();
MealFactory nonVeganMealFactory = new NonVeganMealFactory();
Pizza veganPizza = veganMealFactory.createPizza();
Burger veganBurger = veganMealFactory.createBurger();
Pizza nonVeganPizza = nonVeganMealFactory.createPizza();
Burger nonVeganBurger = nonVeganMealFactory.createBurger();

Since both VeganMealFactory and NonVeganMealFactory are of type PizzaFactory, can’t we just decide between them using a simple decider?

Let’s try it:

public class MealFactoryDecider {private MealFactoryDecider(){}public static MealFactory decide(MealType mealType) {
switch (mealType) {
case VEGAN:
return new VeganMealFactory();
case NONVEGAN:
return new NonVeganMealFactory();
default: throw new RuntimeException("Invalid type.");
}
}
}

And the final client code would be like:

MealFactory veganMealFactory =
MealFactoryDecider.decide(VEGAN);
MealFactory nonVeganMealFactory = MealFactoryDecider.decide(NONVEGAN);Pizza veganPizza = veganMealFactory.createPizza();
Burger veganBurger = veganMealFactory.createBurger();
Pizza nonVeganPizza = nonVeganMealFactory.createPizza();
Burger nonVeganBurger = nonVeganMealFactory.createBurger();

Voila!

Remember to combine multiple patterns if you feel like it’ll be a good fit.

Wrap-Up

Simple Factory relies on readability: while it may not be considered a design pattern, it’s a simple way to decouple your clients from concrete classes.

Factory Method relies on inheritance: object creation is delegated to subclasses which implement the specific factory method to create objects.

Abstract Factory relies on composition: object creation is implemented in multiple methods exposed in the factory interface.

All factory patterns promote loose coupling by reducing the dependency of your application on concrete classes.

Thank you for reading and being a part of my journey!

Reference(s)

  • Head First Design Patterns. by Eric Freeman, Elisabeth Robson, Bert Bates, Kathy Sierra. Released October 2004. Publisher(s): O’Reilly Media, Inc.

--

--