Factory Pattern in Python

Do not miss this exclusive book on Binary Tree Problems. Get it now for free.

In this article, we have explained the idea of Factory Pattern in Python with a complete Python implementation example.

Table of contents:

  1. Introduction to Factory Pattern
  2. Reasons for using Factory Method
  3. Implementations without using Factory Method
  4. Problem with using the non-factory method
  5. Implementations using Factory Method
  6. Solution offered by using Factory Method

Introduction to Factory Pattern

Factory method also known as Virtual Constructor is a Creational Design Pattern which allow reusing of existing code and increased flexibilty. This define an interface to create objects in a superclass but it is the subclasses that determine the type of object that will be created.

Reasons for using Factory Method

The Factory Method Design Pattern seek to loosen the coupling in the code. This is done by creating an abstract class which will be then be used to create various different types of objects.

The objects created will share some common attributes and functionality. Thus leading to the reuse of existing code and increased flexibilty because the shared functionality will inherited from the same class.

Implementations without using Factory Method

class BeefBurger:
    def cook(self):
        print('Beef Burgers')

class ChickenBurger:
    def cook(self):
        print('Chicken Burger')
        
class FishBurger:
    def cook(self):
        print('Fish Burger')

if __name__ == '__main__':
    
    bb = BeefBurger()
    cb = ChickenBurger()
    fb = FishBurger()
    
    # Create burger "Beef burger"
    bb.cook()
    
    # Create burger "Chicken burger"
    cb.cook()
    
    # Create burger "Fish burger"
    fb.cook()

Output

Beef Burgers
Chicken Burger
Fish Burger

Problem with using the non-factory method

Let say a new class CheeseBurger is required, the common attributes and functionality among the other Burger classes will need to be repeated in the codes. If there is an update in the common attributes and functionality, all the Burger classes will need to be updated.

Implementations using Factory Method

We start by creating the Object Interface, the common attributes and functionality among the various Burgers classes are written and stored in the Burger class.

# Object Interface
class Burger(object):
    def cook(self):
        pass

class BeefBurgers(Burger):
    def cook(self):
        print('Beef Burgers')

class ChickenBurger(Burger):
    def cook(self):
        print('Chicken Burger')
        
class FishBurger(Burger):
    def cook(self):
        print('Fish Burger')

Next the Factory Object is created. The library's Factory (BurgerStoreFactory) will accept an input (i.e. what burger) and decide which object type (burger) to create.

# Factory Object
class BurgerStoreFactory(object):
    @staticmethod
    def getBurger(name):
        if name == 'Beef':
            return BeefBurgers()
        elif name == 'Chicken':
            return ChickenBurger()
        elif name == 'Fish':
            return FishBurger()

In the client code portion, we will make a call to library's Factory (BurgerStoreFactory) create method and pass the type of object (burger) we want without having to worry about how the creation of objects is actually implemented

# Client Code
if __name__ == '__main__':
    
    # Create burger "Beef burger"
    b = BurgerStoreFactory()
    burger = b.getBurger('Beef')
    burger.cook()
    
    # Create burger "Chicken burger"
    burger = b.getBurger('Chicken')
    burger.cook()
    
    # Create burger "Fish burger"
    burger = b.getBurger('Fish')
    burger.cook()

Output

Beef Burgers
Chicken Burger
Fish Burger

Solution offered by using Factory Method

In this instance, the selection of type for object creation is decoupled from the Client code. The common attributes and functionality among the other Burger classes will not repeated in the codes.

Here is the entire code block for reference

# Object Interface
class Burger(object):
    def cook(self):
        pass

class BeefBurgers(Burger):
    def cook(self):
        print('Beef Burgers')

class ChickenBurger(Burger):
    def cook(self):
        print('Chicken Burger')
        
class FishBurger(Burger):
    def cook(self):
        print('Fish Burger')

# Factory Object
class BurgerStoreFactory(object):
    @staticmethod
    def getBurger(name):
        if name == 'Beef':
            return BeefBurgers()
        elif name == 'Chicken':
            return ChickenBurger()
        elif name == 'Fish':
            return FishBurger()

# Client Code
if __name__ == '__main__':
    
    # Create burger "Beef burger"
    b = BurgerStoreFactory()
    burger = b.getBurger('Beef')
    burger.cook()
    
    # Create burger "Chicken burger"
    burger = b.getBurger('Chicken')
    burger.cook()
    
    # Create burger "Fish burger"
    burger = b.getBurger('Fish')
    burger.cook()

With this article at OpenGenus, you must have the complete idea of Factory Pattern in Python.

Sign up for FREE 3 months of Amazon Music. YOU MUST NOT MISS.