My Note / Zeliang YAO
  • Zeliang's Note
  • Dremio
    • Custom Class
  • 💕Python
    • Design Pattern
      • Creational
        • Abstract Factory
        • Factory Method
        • Singleton
        • Builder / Director
      • Structural
        • Adapter
    • Boto3
    • Typing
    • String
    • Requests
    • Iterator & Iterable
      • Consuming iterator manually
      • Lazy Iterable
    • Genrators
    • itertools
    • Collections
    • Customization
      • Customize built-in
      • Logging
      • Hdf5
      • Sqlite3 & Df
    • Pandas
      • Basic
      • Data cleaning
      • Merge, Join, Concat
      • Useful tricks
      • Simple model
      • Pandas acceleration
    • Pandas time series
      • Date Range
      • Datetime Index
      • Holidays
      • Function_to_date_time
      • Period
      • Time zone
    • *args and**kwargs
    • Context Manager
    • Lambda
    • SHA
    • Multithreading
      • Threading
      • Speed Up
    • Email
    • Improvement
    • Useful functions
    • Python OOP
      • Basic
      • @static / @class method
      • attrs module
      • Dataclasses
      • Dataclasses example
      • Others
    • Design patterns
      • Creational Patterns
      • Structural Patterns
      • Behavioral Patterns
  • 🐣Git/Github
    • Commands
  • K8s
    • Useful commands
  • Linux
    • Chmod
Powered by GitBook
On this page
  • Factory pattern
  • Simple Factory
  • Factory Method
  • Abstract factory
  • Reference (Chinese)
  • Personal example

Was this helpful?

  1. Python
  2. Design patterns

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()

PreviousDesign patternsNextStructural Patterns

Last updated 3 years ago

Was this helpful?

💕
用Python实现设计模式——工厂模式SegmentFault 思否
Logo