Factory Method Design Pattern

What is the Factory Method Pattern?

In Java applications, you might be often using the new operator to create an object of a class. This is often fine for small Java programs. But when you work on large scale enterprise class applications, the amount of code to create objects will gradually increase and will become scattered across the application. If class names are hard coded in such code, the complexities of managing the code will keep increasing as you add new classes to the application. To address such concerns, you can use the factory method pattern. This pattern is a classic Gang of Four creational design pattern that is concerned with the creation of objects in an application. As the name suggests, the factory method pattern makes use of classes that acts as factories to create objects. This pattern favors method invocation instead of making direct constructor calls to create objects.

In the factory method pattern, you provide an interface, which can be a Java interface or an abstract class to create objects. A factory method in the interface defers the object creation to one or more concrete subclasses at run time. The subclasses implement the factory method to select the class whose objects need to be created.

Participants in the Factory Method Pattern

To understand how the factory method pattern works, consider a pizza store that creates pizzas. In an application, you can model the pizzas as concrete Pizza objects, such as CheesePizza, PepperoniPizza, and VeggiePizza. Just as in any pizza store, where a customer can only order a pizza and not make it, in the application you can create an abstract class, say BasePizzaFactory with a factory method to create a pizza. You can then create a subclass of BasePizzaFactory, called PizzaFactory to implement the factory method. In the factory method, you can create and return a proper Pizza object. The object returned will be the proper subtype, and configured for use in your code.

The components of the factory method pattern in the context of the pizza store can be summarized as:

  • Product (Pizza): Is an interface or an abstract class whose subclasses are instantiated by the factory method.
  • ConcreteProduct (CheesePizza, PepperoniPizza, and VeggiePizza): Are the concrete subclasses that implement/extend Product. The factory method instantiates these subclasses.
  • Creator (BasePizzaFactory): Is an interface or an abstract class that declares the factory method, which returns an object of type Product.
  • ConcreteCreator (PizzaFactory): Is a concrete class that implements the factory method to create and return a ConcreteProduct to Client.
  • Client: Asks the Creator for a Product.

A Client that requires a ConcreteProduct does not create any object but instead asks the Creator for it. The ConcreteCreator implements the factory method to create the object transparently from the Client. As a result the Client is not required to be aware of any ConcreteProduct and how they are created. This approach advocates the Object Oriented Programming principle “Program to an interface, not an implementation“, which leads to polymorphism, a key feature of object-oriented programming. In addition, as object creation is centralized in the ConcreteCreator, any changes made to a Product or any ConcreteProduct does not affect the Client.

Applying the Factory Method Pattern

To apply the factory method pattern in the pizza store application, let us first create the abstract Pizza class and its subclasses.

 

 

In the examples above, we wrote the Pizza class with an abstract addIngredients() method and defined a bakePizza() method. We then wrote three subclasses: CheesePizza, PepperoniPizza, and VeggiePizza that provide their own implementation of the addIngredients() method. The subclasses being derived from Pizza inherit the bakePizza() method defined in Pizza.

Next, we will create the abstract BasePizzaFactory class, which is the Creator in the application.

In the example above, we wrote the BasePizzaFactory class with a createPizza() factory method. Notice that we have declared the createPizza() method as abstract. We will provide the factory method implementation in a concrete subclass, PizzaFactory, which will be the ConcreteCreator of the application.

In the example above, we wrote the PizzaFactory class and implemented the createPizza() factory method in it. In the createPizza() method, we used a switch statement to create a Pizza object based on the parameter passed to the method. We then made calls to the addIngredients() and bakePizza() methods on the Pizza object before returning it to the caller.

Now, let us write a unit test for our example class to observe the factory method pattern at work. In our test, we make two calls to the factory method with different String parameters. The parameter tells our factory what kind of pizza we want.

As you can see in the above example, we have not created any concrete Pizza objects in the code. Therefore, if we enhance the Pizza implementation classes in a newer release, we do not require updating any client or test code. We can safely rely on the Creator to provide us the enhanced object. When you run the code above, you will see this output:

Conclusion

Java APIs and frameworks extensively use the factory method pattern and you should also consider using it because of the advantages it provides. The key advantage that you have already learned is how the factory method pattern helps encapsulate object creation code from client code. This decouples your client code from the concrete classes you need to instantiate. Therefore, while developing applications, if you see an opportunity to encapsulate object creation code, apply the factory method pattern. Also, by using this pattern you will have a centralized location for object creation code, which will make it easy for you to debug and troubleshoot.

Source Code

The source code for this post is available on github. You can download it here.

5 comments on “Factory Method Design Pattern

  1. Hi, I want to make a Factory on Spring Boot (Example: I have Resource, but as an attribute I create other child objects), Can I use this?, I use this on computer enginyeering, but I don’t know if it can be done otherwise on Spring Boot.

    Thanks.

    • Yes you can do this. Spring Boot automates a lot, but it does not prevent you from using traditional Spring configuration.

  2. Hi,
    It looks like PizzaFactory#createPizza implements the Simple Factory Design Pattern, it is not a Factory Method implementation.
    Please have a look at http://corey.quickshiftconsulting.com/blog/first-post and various discussions on StackOverflow.
    P.S.
    I’m trying to make things clear for myself in the first place, so I’m open for the discussion.

  3. I agree; this article demonstrates the Simple Factory design pattern, not the Factory Method pattern.

  4. Hi John:
    Question: If want to put this on a spring boot webapp, what is the best way to persist the created object? would it be injecting the factory into the service and then the factory calls each child’s repository?

Leave a Reply