- is responsible soely for the wholesale creation of objects
- It's like outsourcing the creation of objects involving several steps
- Motivation
- 1. When object creation logic becomes too convoluted
- When initialization procedure becomes too complex, wants to move this part of code somewhere
- 2. Initializer is not descriptive
- (in python) name is always __init__
- cannot overload with same sets of arguments with different names
- can potentially turn into "optional parameter hell"
- Variations of Factory Design Pattern
- 1. A separate method (Factory Method)
- separate methods are static methods
- 2. That may exist in a separate class (Factory)
- Example
- 1. If there is a class called Food, then there would be a FoodFactory class
- 3. Can create hierarchy of factories with abstract factory
Example
from enum import Enum
from math import *
class CoordinateSystem(Enum):
CARTESIAN = 1
POLAR = 2
class Point:
def __str__(self):
return f'x: {self.x}, y: {self.y}'
def __init__(self, a, b):
self.x = a
self.y = b
# take out factory methods to a separate class
class PointFactory:
@staticmethod
def new_cartesian_point(x, y):
return Point(x, y)
@staticmethod
def new_polar_point(rho, theta):
return Point(rho * sin(theta), rho * cos(theta))
if __name__ == '__main__':
p1 = Point(2, 3, CoordinateSystem.CARTESIAN)
p2 = PointFactory.new_cartesian_point(1, 2)
# or you can expose factory through the type
p3 = Point.Factory.new_cartesian_point(5, 6)
p4 = Point.factory.new_cartesian_point(7, 8)
print(p1, p2, p3, p4)
References