Masayan tech blog.

  1. ブログ記事一覧>
  2. Pythonでデザインパターン実践:Factory Method

Pythonでデザインパターン実践:Factory Method

公開日

環境

  • Windows 10
  • Python 3.10.1
  • VSCode

Factory Methodとは

  • インスタンス生成の処理の流れは「親クラス」で決定し、実装先の子クラスで具体的なインスタンの生成処理などを実装する設計パターン
  • Factory Methodは、オブジェクトの生成手順をパターン化したもの

このパターンを適用すると、オブジェクト作成のための手順と実際にオブジェクトを作成する責務を明確に分けて定義することができます

実装する内容

  • スクレイピングで有名なBeautifulSoupのオブジェクトを生成する処理をFactory Methodを活用して構築する

クラス図

  • IFactory
    • インターフェース。オブジェクトの生成手順のみを定義し、実際の生成については、サブクラスで行う。
  • SoupFactory
    • createメソッドでオブジェクトを生成する
    • createメソッドにはurlオブジェクトを引数に取る

実際に作成するオブジェクト自体もインターフェースと実装クラスを定義するとより責務が明確になりますが、今回はそこまでの構成にはしませんでした

実装

普通に書くとこのようになる

from bs4 import BeautifulSoup
import requests

res = requests.get("your url")
BeautifulSoup(res.text, "html.parser")

まず、Factoryクラスを抽象クラスで作成する

Factoryクラスはcreateメソッドをかならず実装する必要があるように指定する

import abc

class IFactory:
    @abc.abstractmethod
    def create(self):
        pass

メソッド名はfactory_methodになっていたり、createになっていたりいろいろあるようですが、今回はcreateとしました

続いて、Factoryクラスを実装する具象クラスを作成する

必ずcreateメソッドを実装し、内部の処理でsoupオブジェクトを生成してreturnする(具体的なインスタンの生成処理)

外部ライブラリ(今回だとbs4)を使用することになりますが、Factoryクラスに対して依存するようにしているので、ライブラリが変わってもcreateメソッドを呼び出す側は特に考慮する必要がなくなります

from bs4 import BeautifulSoup
from shared.i_factory import IFactory
from shared.Domain.xurl import XUrl
import requests

class SoupFactory(IFactory):
    def create(self, xurl: XUrl) -> BeautifulSoup:
        res = requests.get(xurl.get_href())
        return BeautifulSoup(res.text, "html.parser")

実際にオブジェクトを生成する際には、このようにFactoryの具象クラスをnewし、createメソッドに必要な引数を渡してあげるだけで、指定したオブジェクトを取得することが可能になる

また、それぞれのクラスで責務が分けられており、コードも英文のように読みやすくなる

from shared.Domain.Scraping.soup_factory import SoupFactory
from shared.Domain.xurl import XUrl
from shared.i_factory import IFactory

factory: IFactory = SoupFactory()
soup = factory.create(XUrl("https://maasaablog.com/"))

正直なところ、具象クラスがまだ1つしかないのでFactory Methodの恩恵は感じられにくいですが、具象クラスが増えれば増えるほど、コードの書きやすさやメンテナンス性がぐっと向上します

まとめ

いかがでしたでしょうか。本記事では、PythonでFactory Methodパターンを実践する方法について紹介しています。Factory Methodは、オブジェクトの生成手順をパターン化したものです。オブジェクト作成のための手順と実際にオブジェクトを作成する責務を明確に分けて定義することができます