Creational Patterns
Factory pattern
Simple Factory
Without factory
class Mercedes(object):
def __repr__(self):
return "Mercedes-Benz"
class BMW(object):
def __repr__(self):
return "BMW"
mercedes = Mercedes()
bmw = BMW()
With simple factory
class SimpleCarFactory(object):
@staticmethod
def product_car(name):
if name == 'mb':
return Mercedes()
elif name == 'bmw':
return BMW()
c1 = SimpleCarFactory.product_car('mb')
c2 = SimpleCarFactory.product_car('bmw')
Factory Method
Use abstract factory methode to add flexibility
#coding=utf-8
import abc
class AbstractFactory(object):
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def product_car(self):
pass
class MercedesFactory(AbstractFactory):
def product_car(self):
return Mercedes()
class BMWFactory(AbstractFactory):
def product_car(self):
return BMW()
c1 = MercedesFactory().product_car()
c2 = BMWFactory().product_car()
Abstract factory
Now let's make it better, we can produce SUV or normal car
#coding=utf-8
import abc
# 两种小汽车
class Mercedes_C63(object):
def __repr__(self):
return "Mercedes-Benz: C63"
class BMW_M3(object):
def __repr__(self):
return "BMW: M3"
class Mercedes_G63(object):
def __repr__(self):
return "Mercedes-Benz: G63"
class BMW_X5(object):
def __repr__(self):
return "BMW: X5"
class AbstractFactory(object):
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def product_car(self):
pass
@abc.abstractmethod
def product_suv(self):
pass
class MercedesFactory(AbstractFactory):
def product_car(self):
return Mercedes_C63()
def product_suv(self):
return Mercedes_G63()
class BMWFactory(AbstractFactory):
def product_car(self):
return BMW_M3()
def product_suv(self):
return BMW_X5()
c1 = MercedesFactory().product_car()
s1 = MercedesFactory().product_suv()
print(c1, s1)
s2 = BMWFactory().product_suv()
c2 = BMWFactory().product_car()
print(c2, s2)
Reference (Chinese)
Personal example
Read data from csv and filter on it based on requirements
import hashlib
import abc
from collections import namedtuple
# Build data type
basic_cols = ['a','b','c'... ,'hash_d=id']
fields = " ".join(basic_cols)
Data = namedtuple('Data',fields,defaults=""* len(fields))
class Datafactory:
__metaclass__ = abc.ABCMeta
source = []
def __init__(self,file_name):
if self.source==[]:
print("Reading data...")
with open(file_name,encoding='utf-8') as file:
file_iter = iter(file)
# Jump first line
_ = next(file_iter)
for line in file_iter:
each_ine = line.strip("\n").split(";")+['']
self.source.append(Data(*each_line))
print("Finish")
print("Add hash_id ...")
self.source = list(map(self.create_hash_id,self.source))
@staticmethod
def create_hash_id(each):
text = "".join(x.replace(" ","") for x in each._asdict().values())
return each._replace(hash_id = hashlib.sha256(text.encode('utf-8').hexdigest())
@abc.abstractmethod
def produce_data(self):
pass
class D1_Factory(DataFactory):
def __init__(self,file_name):
super().__init__(file_name)
print("Apply D1 filter...")
self.d1_data = list(filter(self.apply_filter,self.source))
print("Done")
@staticmethod
def apply_filter(e):
return (e.a=='xxx' and e.b in [1,24] and ..)
def produce_data(self):
return pd.DataFrame(self.d1_data,columns = Data._fields)
class C1_Factory(DataFactory):
def __init__(self,file_name):
super().__init__(file_name)
print("Apply C1 filter...")
self.c1_data= list(filter(self.apply_filter,self.source))
print("Done")
@staticmethod
def apply_filter(e):
return (e.c=='c1')
def produce_data(self):
return pd.DataFrame(self.c1_data,columns = Data._fields)
D1_data = D1_Factory('data.csv').produce_data()
C1_data = C1_Factory('data.csv').produce_data()
Last updated