Factory Pattern

Nitin Verma
6 min readApr 16, 2019

--

Welcome to second pattern in my Design pattern series. Before reading this story make sure that you have read Introduction to design patterns.

Prerequisite:

  1. Again make sure that you have read Introduction to design patterns.
  2. You understand java or any other OOP language
  3. you have basic idea about inheritance, polymorphism, interfaces
  4. you find my stories interesting 😉

Let’s say that you want to start a new pizza shop. You serve different kinds of pizzas and obviously you also have menu. Let’s see a method that might appear in our Pizaa store code.

public Pizza orderPizza(String type) {
Pizza pizza;
if (type.equals("cheese"))
pizza = new CheesePizza();
else if (type.equals("clam"))
pizza = new ClamPizza();
else if (type.equals("veggie"))
pizza = new VeggiePizza();
else
return null;
//once we have correct type of pizza, do operations on it
pizza.prepare()
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}

So first we make a correct type of pizza by using if-else blocks and then we perform operations on it. please note that prepare,bake,cut,box doesn’t depend upon type of pizza that we are instantiating. All it cares is that we call these methods on a Pizza(supertype obviously)

Now see this part of above code:

if (type.equals("cheese"))
pizza = new CheesePizza();
else if (type.equals("clam"))
pizza = new ClamPizza();
else if (type.equals("veggie"))
pizza = new VeggiePizza();

If you have done coding a lot then you know that this type of code occurs very frequently in any project. you can easily imagine that similar code block will also appear when we are making bill for a user and a lot of other places. we know that change is the only constant in any software project. Let’s say we want to add a new type of pizza or delete clamPizza then making changes in this type of code is even more difficult because we have to go to every place and make same changes.

Now let’s move object creation out of orderPizza() method into a separate class SimplePizzaFactory whose job is just to create a pizza.

Now our code from PizzaStore has reduced to this:

It might look like that the changes that we made has no advantage. We are just pushing the problem off to another object.
But remember that by doing this, we have reduced code duplication and now we have only one place to make changes when required in future. and this is not the final design. This is just the introduction to the world of factories 😃

Now let’s discuss about simple factories. our class diagram looks like this:

PizzaStore: This class is the client of the factory. It need SimplePizzaFactory to get instance of type Pizza.
SimplePizzaFactory: This is the factory where we create pizzas. It should be the only part of our application that refers to concrete Pizza classes.
Pizza: This is the product of the factory. here this is a abstract class which has some methods already implemented.
Concrete Pizza classes: these are our concrete products. Each of them should extend Pizza class. As long as this is the case, our factory can create instance and hand it back to the client. Here they are CheesePizza, ClamPizza, VeggiePizza.

Now you have learned about simple factory. Remember that they always have a client and a product. This is what factories are for, they create products(in real world and in softwares too !!)

Time for a break 😃 ✌️

Photo by Adeolu Eletu on Unsplash

Your pizza shop has now become famous and everyone loves it. You want to expand your business to New York and Chicago. Let’s see how you can do this:

Approach 1: You can make different factories for New York and Chicago whose names will be NYPizzaFactory and ChicagoPizzaFactory respectively. We will also have NYStylePizzas and ChicagoStylePizzas. Factory will instantiate proper type of pizza. I won’t go into much detail as we will focus on approach 2. But here’s how we will order pizza with this approach

NYPizzaFactory nyFactory = new NYPizzaFactory();
PizzaStore nyStore = new PizzaStore(nyFactory);
nyStore.order("cheese");

Approach 2: Now we will tie the store and the pizza creation together. So instead of having multiple factories, we will have multiple stores. Let’s discuss about it in detail

In case you want to see the full code, see this repository. you can import the project in Netbeans.

Now we will move our createPizza factory method back into PizzaStore but as a abstract method. now our PizzaStore will also be a abstract class. Each region will have it’s own PizzaStore type which will extend this PizzaStore and provide implementation for createPizza method(make instance of concrete Pizza type) eg:NYPizzaStore will make different type of NYStylePizzas.

Let’s see one of the sub-type of PizzaStore and see what exactly it is doing

So now instantiation is handled by sub-classes of PizzaStore in their overrided createPizza method. abstract createPizza() method in abstract PizzaStore class act as a factory method. It returns a product( here type Pizza) and this product is used in orderPizza method.

//Here's how you can order pizza using this approach
PizzaStore store = new NYPizzaStore();
Pizza pizza = store.orderPizza("cheese");

In the above code when we call store.orderPizza("cheese") , then orderPizza() method of PizzaStore will be called and futher this method will createPizza() method, but createPizza is abstarct in this class and has no implementation, so what will it do? It all depends on which sub-class of PizzaStore in instantiated. As we have instantiated NYPizzaStore, so createPizza() of NYPizzaStore will be called, and it will return appropriate Pizza type.

So when orderPizza() calls createPizza() , one of your subclasses will be called into action to create a pizza. which kind of pizza will be made? it’s decided by the choice of pizza store you order from. NYStylePizzaStore will return NYStylePizza and ChicagoStylePizzaStore will return ChicagoStylePizza.

All factory patterns encapsulate object creation by letting subclasses decide what object to create. Let’s check the class diagram to see main components

creators and products

Key points:

  1. abstract creator class defines a abstract factory method that subclasses implement to produce products. Here createPizza is our factory method. It produces products.
  2. Often the abstract creator class contains code that depends on product of factor method which is produced by sub class.
  3. classes that produce products are called concrete creators
  4. Factories produce products and here our product is pizza

Factory method defined:

This pattern defines an interface for creating an object, but lets subclasses decide which class to instantiate. Factory method lets a class defer instantiation to subclasses.

Creator class is written without the knowledge of the actual products that will be created, it is decided purely by the choice of the subclass that is used.

general design

Wanna learn about Abstract Factory pattern also? see my story on it.

Clap 👏 , Comment and share your valuable feedback and don’t forget to ask more questions in comment section below (if you have any 😉) ✌️

References:
- Head first design patterns book.

--

--

Nitin Verma

Android developer, GIS, writer, Punjabi who love to share knowledge ✌️