Open-Source Internship opportunity by OpenGenus for programmers. Apply now.
In this article, we have explained the idea of Factory Pattern in Python with a complete Python implementation example.
Table of contents:
- Introduction to Factory Pattern
- Reasons for using Factory Method
- Implementations without using Factory Method
- Problem with using the non-factory method
- Implementations using Factory Method
- 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.