Python Factory Pattern

Find out why this 'anti-pattern' is useful

It is easy to implement the Factory Pattern in Python and there are at least two reasons to use it.

Watch the video to find out.

Example source

You can find a copy of the source code below to experiment with:

from abc import ABC, abstractmethod
import random
#######
# The factory pattern
#######

class Vehicle(ABC):
	"""
	Creates "An Abstract class aka interface"
	"""
	
	# Interface - number of wheels
	@abstractmethod
	def get_num_wheels(self):
		pass
	
	# Interface - vehicle name/make
	@abstractmethod
	def get_name(self):
		pass
	
	# Interface - vehicle color
	@abstractmethod
	def get_color(self):
		pass
		
class Car(Vehicle):
	"""
	Type: Concrete class
	Abstract methods of the Vehicle base class are implemented here.
	"""
	# Interface - see the number of wheels
	def __init__(self,name,color,ID):
		self.name = name
		self.color = color
		self._id = ID
		self.wheels = 4
		
	def get_num_wheels(self):
		return(self.wheels)
		
	def get_color(self):
		return(self.color)
		
	def get_name(self):
		return(self.name)
				
	def __str__(self):
		return f'{type(self).__name__}:{self.name},{self.color},id {self._id}'
		
class Truck(Vehicle):
	"""
	Type: Concrete class
	Abstract methods of the Vehicle base class are implemented here.
	"""
	# Interface - see the number of wheels
	def __init__(self,name,color,ID):
		self.name = name
		self.color = color
		self._id = ID
		self.wheels = 6
		
	def get_num_wheels(self):
		return(self.wheels)
		
	def get_color(self):
		return(self.color)
		
	def get_name(self):
		return(self.name)
				
	def __str__(self):
		return f'{type(self).__name__}:{self.name},{self.color},id {self._id}'


class VehicleFactory():
	"""
	Returns a vehicle of your choice.
	"""
	def get_unique_id(self):
		return(random.randint(100,100_000))
	
	def get_vehicle(self, vtype, name, color):
		if vtype == Car.__name__:
			return Car(name,color,self.get_unique_id())
			
		if vtype == Truck.__name__:
			return Truck(name,color,self.get_unique_id())
			
if __name__ == "__main__":
	
	vf = VehicleFactory()
	print(vf.get_vehicle('Car','Alto','Black'))
	print(vf.get_vehicle('Truck','Tata','Yellow'))
	print(vf.get_vehicle('Truck','Benz','Orange'))
	print(vf.get_vehicle('Car','Celerio','Blue'))

''' Sample output
	
$ python3 vehicle_abstract_factory_pattern.py 
Car:Alto,Black,id 6119
Truck:Tata,Yellow,id 78345
Truck:Benz,Orange,id 17334
Car:Celerio,Blue,id 11868

'''	

Takeaway

The factory pattern is an elegant way to create objects in your program and can lead to clean and maintainable code.