【Python デザインパターン】FactoryMethodパターン

Pythonで学ぶデザインパターン

FactoryMethodパターン

インスタンスを作成する工場(Factory)、フレームワークを

TemplateMethodパターンを用い実現させるものが、FactoryMethodパターンです。

 

 

サンプルプログラム

今回は単体テスト用フォルダ作成のサンプルプログラムをFactoryMethodを用いて考えます。

単体テストフォルダ構成は下記です。

root
 └<unit-test>
       ├src
       ├input
       └output

 

Factory(工場)クラス

class AbstractFactory:
    def create(self,owner):
        p = self.createProduct(owner)
        self.registerProduct(p)
        return p
    def createProduct(self,owner):
        pass
    def registerProduct(self,product):
        pass

Productを作成し登録する流れのみ実装しています。
どのように作成・登録するかはサブクラスの実装に委ねます。

Productクラス

class Product:
    def use(self):
        pass

Productではuseメソッドのみを抽象メソッドとして定義しています。

UnitTestFolderFactory(Factoryの実装)

class UnitTestFolderFactory(AbstractFactory):
    def __init__(self,basename):
        self.unittest_base =os.path.dirname(__file__)
        if basename != "":
            self.unittest_base = os.path.join(self.unittest_base,basename)
        self.unittest =[]
    def createProduct(self,folder):
        if(folder==""):
            print("フォルダ名が不明です")
            return None
        self.path = os.path.join(self.unittest_base,folder)
        return UnitTestFolder(self.path)

    def registerProduct(self,folder):
        if folder is None :
            return
        self.unittest.append(folder.unittestName())

    def printUnittestFolderList(self):
        print("登録されている作成予定リスト")
        for child in self.unittest:
            print(child)

UnitTestフォルダインスタンスを作成し、登録する工場です。

実際のフォルダ作成はUnitTestフォルダインスタンスで行います。

 

UnitTestFolder(Productの実装)

class UnitTestFolder(Product):

    def __init__(self,folder):
        print(folder+"を作成します。")
        self.folder = folder
    def use(self):
        children = ["src","input","output"]
        if self.folder =="" :
            print("フォルダ名が不明です")
            return
        os.makedirs(self.folder)
        for child in children:
            path = os.path.join(self.folder,child)
            os.makedirs(path)
    def unittestName(self):
        return os.path.basename(self.folder)

UnitTestフォルダを表現するProductクラスです。

useメソッドにより、実際に自身のUnitTestフォルダが作成します。

 

ソースコード全般

import os
class AbstractFactory:
    def create(self,owner):
        p = self.createProduct(owner)
        self.registerProduct(p)
        return p
    def createProduct(self,owner):
        pass
    def registerProduct(self,product):
        pass
        
class Product:
    def use(self):
        pass

class UnitTestFolderFactory(AbstractFactory):
    def __init__(self,basename):
        self.unittest_base =os.path.dirname(__file__)
        if basename != "":
            self.unittest_base = os.path.join(self.unittest_base,basename)
        self.unittest =[]
    def createProduct(self,folder):
        if(folder==""):
            print("フォルダ名が不明です")
            return None
        self.path = os.path.join(self.unittest_base,folder)
        return UnitTestFolder(self.path)

    def registerProduct(self,folder):
        if folder is None :
            return
        self.unittest.append(folder.unittestName())

    def printUnittestFolderList(self):
        print("登録されている作成予定リスト")
        for child in self.unittest:
            print(child)


class UnitTestFolder(Product):

    def __init__(self,folder):
        print(folder+"を作成します。")
        self.folder = folder
    def use(self):
        children = ["src","input","output"]
        if self.folder =="" :
            print("フォルダ名が不明です")
            return
        os.makedirs(self.folder)
        for child in children:
            path = os.path.join(self.folder,child)
            os.makedirs(path)
    def unittestName(self):
        return os.path.basename(self.folder)

if __name__ == '__main__':
    factory = UnitTestFolderFactory("unittest")
    unit0 = factory.create("unittest0")
    unit1 = factory.create("unittest1")
    unit2 = factory.create("unittest2")
    unit0.use()
    unit1.use()
    unit2.use()
    factory.printUnittestFolderList()

 

FactoryMethodパターンでは

作成者(AbstractFactory)と作成されるモノ(Product)が存在し、

Factoryの作成メソッドによりProductが作成されます。(フレームワーク)

作成する方法はフレームワークによって決まっているため、あとは実際の作成者とモノを実装するのみです。

今回は単体テスト(UnitTest)に使用するフォルダを作成する工場をサンプルとして作成しました。

 

あわせて読みたい