🐘
【Python】デザインパターン学習 - Abstract Factoryパターン -
作成日:
2021/12/05
0
Abstract Factoryパターンについて学ぶ
参考サイト1の動画で紹介されているTypeScriptのコードを自分なりにpythonに書き直して学習する。
Abstract Factoryパターンとは
状況が違うときに生成するオブジェクトを丸ごと切り替えるのに使えるパターン。
pythonでの書き方
from abc import ABCMeta, abstractmethod
import json
env = 'test'
class CustomerList(metaclass=ABCMeta):
@abstractmethod
def get_all(self):
pass
@abstractmethod
def fetch(self):
pass
class CustomerTable(CustomerList):
def __init__(self):
self.data = self.fetch()
def get_all(self):
print(self.data)
return self.data
def fetch(self):
# 本来はAPI通信で取得してくる想定
return [
{'name': '田中一郎', 'gender': 'male'},
{'name': '鈴木二郎', 'gender': 'male'},
{'name': '山田花子', 'gender': 'female'},
{'name': '太田武', 'gender': 'male'},
{'name': '山岡涼子', 'gender': 'female'}
]
class TestCustomerTable(CustomerList):
def __init__(self):
self.data = self.fetch()
def get_all(self):
print('get_allのテスト実行')
print(self.data)
return self.data
def fetch(self):
# 本来はテスト用のファイルロード等から取得してくる想定
return [
{'name': 'テスト一郎', 'gender': 'male'},
{'name': 'テスト二郎', 'gender': 'male'},
{'name': 'テスト花子', 'gender': 'female'}
]
class Serializer(metaclass=ABCMeta):
@abstractmethod
def serialize(self, data):
pass
class JsonSerializer(Serializer):
def serialize(self, data):
return json.dumps(data)
class TestJsonSerializer(Serializer):
def serialize(self, data):
print('serializeのテスト実行')
return json.dumps(data)
class CustomerListAbstractFactory(metaclass=ABCMeta):
@abstractmethod
def create_customer_table(self):
pass
@abstractmethod
def create_serializer(self):
pass
class CustomerTableFactory(CustomerListAbstractFactory):
def create_customer_table(self):
return CustomerTable()
def create_serializer(self):
return JsonSerializer()
class TestCustomerTableFactory(CustomerListAbstractFactory):
def create_customer_table(self):
return TestCustomerTable()
def create_serializer(self):
return TestJsonSerializer()
if env != "test":
factory = CustomerTableFactory()
else:
factory = TestCustomerTableFactory()
CUSTOMER_TABLE = factory.create_customer_table()
RESULT = CUSTOMER_TABLE.get_all()
SERIARIZER = factory.create_serializer()
print(SERIARIZER.serialize(RESULT))
実行結果
>python .\example.py
[{'name': '田中一郎', 'gender': 'male'}, {'name': '鈴木二郎', 'gender': 'male'}, {'name': '山田花子', 'gender': 'female'}, {'name':'太田武', 'gender': 'male'}, {'name': '山岡涼子', 'gender': 'female'}]
[{"name": "\u7530\u4e2d\u4e00\u90ce", "gender": "male"}, {"name": "\u9234\u6728\u4e8c\u90ce", "gender": "male"}, {"name": "\u5c71\u7530\u82b1\u5b50", "gender": "female"}, {"name": "\u592a\u7530\u6b66", "gender": "male"}, {"name": "\u5c71\u5ca1\u6dbc\u5b50", "gender": "female"}]
>python .\example.py
get_allのテスト実行
[{'name': 'テスト一郎', 'gender': 'male'}, {'name': 'テスト二郎', 'gender': 'male'}, {'name': 'テスト花子', 'gender': 'female'}]
serializeのテスト実行
[{"name": "\u30c6\u30b9\u30c8\u4e00\u90ce", "gender": "male"}, {"name": "\u30c6\u30b9\u30c8\u4e8c\u90ce", "gender": "male"}, {"name": "\u30c6\u30b9\u30c8\u82b1\u5b50", "gender": "female"}]
書いた感想
クラスを生成するだけのクラスを作っているところがポイントかなと思う。この例のようにテストと本番で切り替えて実行したいときにも使えるし、この条件によってクラスを切り替えるという構造自体は他のパターンでも使えるのではと感じた。
書いたコード
参考サイト
フリーランスでpythonエンジニアとして働きたく勉強中。
前職は運用SEとセキュリティエンジニア。
開発は学校で学んだ経験と趣味でやっていた程度。一応前職でも業務の自動化のためにExcel VBAやセキュリティテスト用のWebサイトの開発やセキュリティテストツールの改良などで開発はやっていた。