(オススメ2) Python基礎 オブジェクト指向5(Factory Method) 生成に関するデザインパターン
| 登録日 | :2025/09/25 04:50 |
|---|---|
| カテゴリ | :Python基礎 |
Factory Methodとは
親クラスでインスタンスの生成方法を定め、具体的に何をどうやって作るかは子クラスで定めるようなパターン
生成したいオブジェクトのコンストラクタを呼び出してインスタンスを生成するのではなく、親クラスに定義された生成用のメソッドを呼び出してインスタンスの生成を行う
Template Methodを応用したパターン
生成に関するデザインパターン
Factory Methodの構成要素
Creator
- Productを生成する抽象クラス
- Productの生成を行うcreateメソッド
- 具体的な生成方法を実装するためのAPIを提供
ConcreteCreator
- Creatorを継承したクラス
- 製品生成のための具体的な方法を実装
- ConcreteProductクラスのインスタンスを返却
Product
- Creatorのオブジェクト生成メソッドで生成される抽象クラス or インターフェース
- 生成される製品が持つべきAPIを定義する
ConcreteProduct
- Productを継承(実装)したクラス
- ProductのAPIに沿った具体的な製品の機能を実装
Factory Methodのオブジェクト指向的要素
継承を利用したパターン
-
ProductとConcreteProduct, CreatorとConcreteCreatorの間にそれぞれ継承関係がある
-
Template Methodと同様に、処理(生成)の枠組みを親クラスで決定し、子クラスごとに具体的な生成方法を実装する
メリット・デメリット
メリット
-
オープンクローズドの原則に違反することなく新しいProductを追加することができる
-
オブジェクトの利用側とオブジェクトの結びつきを弱くする
デメリット
- 簡単な生成処理の場合はFactory Methodを使用しない方がコードがシンプルになる
Factory Methodの使い所
-
類似した複数種類のオブジェクトを生成する必要がある場合
オープンクローズドの原則に違反することなく、別のオブジェクトの追加が可能 -
オブジェクトの生成ロジックが複雑な場合
createメソッドを呼び出すだけで複雑な生成ロジックを記述せずに生成可能 -
Productの種類や生成手順が頻繁に変更される可能性がある場合
利用側とProductの結びつきが弱いので、変更に強い設計となる
サンプルコード
クレジットカードを生成する例
from abc import ABCMeta, abstractmethod
from typing import List
class CreditCard(metaclass=ABCMeta):
"""Product Factory"""
def __init__(self, _owner: str):
self.__owner = _owner
@property
def owner(self) -> str:
return self.__owner
@abstractmethod
def get_card_type(self) -> str:
pass
@abstractmethod
def get_annual_charge(self) -> int:
pass
class Platinum(CreditCard):
def get_card_type(self) -> str:
return "Platinum"
def get_annual_charge(self) -> int:
return 30000
class Gold(CreditCard):
def get_card_type(self) -> str:
return "Gold"
def get_annual_charge(self) -> int:
return 10000
class CreditCardFactory(metaclass=ABCMeta):
"""Create Factory"""
@abstractmethod
def create_credit_card(self, _owner: str) -> CreditCard:
pass
@abstractmethod
def register_credit_card(self, credit_card: CreditCard):
pass
def create(self, _owner: str) -> CreditCard:
credit_card = self.create_credit_card(_owner)
self.register_credit_card(credit_card)
return credit_card
credit_card_database: List[CreditCard] = []
class PlatinumCreditCardFactory(CreditCardFactory):
def create_credit_card(self, _owner: str) -> CreditCard:
return Platinum(_owner)
def register_credit_card(self, credit_card: CreditCard):
credit_card_database.append(credit_card)
class GoldCardFactory(CreditCardFactory):
def create_credit_card(self, _owner: str) -> CreditCard:
return Gold(_owner)
def register_credit_card(self, credit_card: CreditCard):
credit_card_database.append(credit_card)
if __name__ == '__main__':
platinum_card_factory = PlatinumCreditCardFactory()
platinum_card = platinum_card_factory.create("Tanaka")
print(platinum_card.get_card_type())
gold_credit_card_factory = GoldCardFactory()
gold_card = gold_credit_card_factory.create('Suzuki')
print(gold_card.get_card_type())
print(credit_card_database)