Design Patterns: The Factory Pattern in Java
by Riley MacDonald, August 12, 2017

Introduction
The factory pattern decouples dependencies making it possible to construct objects without really knowing what the exact class is.

This post uses stores which sell different types Sandwiches as an example. To simplify the example, the Sandwiches don’t have any functionality and they’re constructed using Strings instead of enums or more elegant techniques.

Example Class Dependency Problem
To implement this functionality you might start by creating a sandwich store which returns Sandwich implementations per the provided Type. Here’s an example of a class which instantiates several subclasses of Sandwich:

public class SandwichStore {
    Sandwich sandwich;
 
    public SandwichStore(String type) {
        if (type.equals("smoked")) {
            sandwich = new SmokedMeatSandwich();
        } else if (type.equals("sausage")) {
            sandwich = new SujukSausageSandwich();
        } else if (type.equals("beef")) {
            sandwich = new BeefSandwich();
        } else if (type.equals("steak")) {
            sandwich = new SteakSandwich();
        } else sandwich = new PlainSandwich();
    }
}

The SandwichStore has a lot of object dependencies. Maintaining a method like this can be costly as new features and requirements change. According to the dependency inversion principle classes should not depend on concrete subclasses, instead they should depend on abstractions (you should program against interfaces not implementations). The above example violates this principle.

Implementing the Factory Pattern
The factory pattern can be implemented by writing an abstract “construction” method. Implementers of this method are responsible for the instantiation of the classes. Let’s re factor the above method to utilize the factory pattern.

Let’s start by moving the SandwichStores into subclasses of an abstract class. This will be our “abstract construction method”. For this example we’ll create implementations called MontrealSandwich and ItalianSandwich stores. Each of these classes will be responsible for instantiating their perspective Sandwiches.

public abstract class SandwichStore {
    public abstract Sandwich createSandwich(String type);
}
 
public class MontrealSandwichStore extends SandwichStore {
    @Override
    public Chair createSandwich(String type) {
        if (type.equals("smoked")) {
            return new SmokedMeatSandwich();
        } else if (type.equals("sausage")) {
            return new SujukSausageSandwich();
        } else return new PlainSandwich();
    }
}
 
public class ItalianSandwichStore extends SandwichStore {
    @Override
    public Chair createSandwich(String type) {
        if (type.equals("beef"))
            return new BeefSandwich();
        else if (type.equals("steak"))
            return new SteakSandwich();
        else return new PlainSandwich();
    }
}

Utilizing the new Sandwich Stores
Here’s an example of creating Sandwiches externally using what we’ve implemented above.

public class SandwichSaleMachine {
    SandwichStore montrealSandwichStore = new MontrealSandwichStore();
    SandwichStore italianSandwichStore = new ItalianSandwichStore();
 
    public static void main(String[] args) {
        Sandwich montrealSmokedMeatSandwich = montrealSandwichStore.createSandwich("smoked");
        Sandwich italianBeefSandwich = italianSandwichStore.createSandwich("beef");
    }
}

Summary
Since all the different types of Sandwich are encapsulated to their own classes future maintenance is much easier. We’re nicely programming against abstract / interfaces instead of implementations too.

Abstract Factory Method
The abstract factory method is another layer of abstraction for this design pattern. It’s generally used for creating families of products. See my post on The Abstract Factory Method which extends this example and further customizes the creation of the Sandwiches.

Open the comment form

Leave a comment:

Comments will be reviewed before they are posted.

User Comments:

Design Patterns: The Template Pattern in Java | Riley MacDonald on 2017-10-09 16:08:50 said:
[…] making logic in high level modules reducing dependency rot. This pattern has some similarity to the Factory Pattern and the Strategy Pattern. Implementation of the template pattern throughout Javas source code […]

Design Patterns: The Abstract Factory Pattern in Java | Riley MacDonald on 2017-08-19 13:22:54 said:
[…] is an extension of my previous post regarding the Factory Pattern in Java. The Abstract Factory pattern is generally used to create a family of dependent or related […]