TIL: Factory Method
Today I learned about factory pattern.
Factory pattern is used to construct a class instance. It solves the problem that if there’s plenty of specific implementations, the class constructor is not very clean.
Consider:
import json
import xml.etree.ElementTree as et
class Song:
def __init__(self, song_id, title, artist):
self.song_id = song_id
self.title = title
self.artist = artist
class SongSerializer:
def serialize(self, song, format):
if format == 'JSON':
song_info = {
'id': song.song_id,
'title': song.title,
'artist': song.artist
}
return json.dumps(song_info)
elif format == 'XML':
song_info = et.Element('song', attrib={'id': song.song_id})
title = et.SubElement(song_info, 'title')
title.text = song.title
artist = et.SubElement(song_info, 'artist')
artist.text = song.artist
return et.tostring(song_info, encoding='unicode')
else:
raise ValueError(format)
This could be changed to:
class SongSerializer:
def serialize(self, song, format):
serializer = self._get_serializer(format)
return serializer(song)
def _get_serializer(self, format):
if format == 'JSON':
return self._serialize_to_json
elif format == 'XML':
return self._serialize_to_xml
else:
raise ValueError(format)
def _serialize_to_json(self, song):
payload = {
'id': song.song_id,
'title': song.title,
'artist': song.artist
}
return json.dumps(payload)
def _serialize_to_xml(self, song):
song_element = et.Element('song', attrib={'id': song.song_id})
title = et.SubElement(song_element, 'title')
title.text = song.title
artist = et.SubElement(song_element, 'artist')
artist.text = song.artist
return et.tostring(song_element, encoding='unicode')
This is much cleaner, it’s easier to read and easier to add another format.