🐘 【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"}]

書いた感想

クラスを生成するだけのクラスを作っているところがポイントかなと思う。この例のようにテストと本番で切り替えて実行したいときにも使えるし、この条件によってクラスを切り替えるという構造自体は他のパターンでも使えるのではと感じた。

書いたコード

github

参考サイト

  1. Abstract Factoryパターン【コードで理解する】- プログラミング相談所オンライン

フリーランスでpythonエンジニアとして働きたく勉強中。 前職は運用SEとセキュリティエンジニア。 開発は学校で学んだ経験と趣味でやっていた程度。一応前職でも業務の自動化のためにExcel VBAやセキュリティテスト用のWebサイトの開発やセキュリティテストツールの改良などで開発はやっていた。