Factory Methodパターン

結城浩さんの「Java言語で学ぶデザインパターン入門」を題材にpythonデザインパターン
書いてみる。今回の題材はFactory Methodパターン。
前回書いたTemplate Methodパターンはスーパークラスで処理の大枠を作って、サブクラスで
具体的処理を決定するというものだった。
このパターンをインスタンスをつくる場面に適用したものがFactory Methodパターンというものみたい。
今回のサンプルプログラム(factory_method.py)はIDカードを作る工場を仮定したもの。
それでは書いてみる。
最初はProductクラス

class Product(object):
    def use(self):
        pass

ここは「製品」を表現したクラス。Javaで書いたときの抽象メソッドuseが宣言されているので、pythonでもuseメソッドの宣言のみ。
次はFactoryクラス

class Factory(object):
    def create(self, owner):
        p = self.createProduct(owner)
        self.registerProduct(p)
        return p

    def createProduct(self, owner):
        pass

    def registerProduct(self, product):
        pass

ここではTemplate Methodパターンが使われている。Template Methodパターンって何だったかというと
スーパークラスで処理の大きな枠組みを決めておいて、サブクラスでその具体的処理を決める」だった。
今回に当てはめるとこのクラスは処理の大きな枠組みを規定しているものになる。
具体的な処理が決まっていないcreateProductとregisterProductの両メソッドで「製品を作り」、「登録する」
が実装はサブクラスが担う。
createメソッドではcreateProductとregisterProductの両メソッドを使って「製品」のインスタンスを生成しているわけだ。
Factory Methodパターンではインスタンス生成にTemplate Methodパターンが使われる。
つづいてIDCardクラス

class IDCard(Product):
    def __init__(self, owner):
        self.owner = owner
        print "make %s's card" %(self.owner)

    def use(self):
        print "use %s's card" %(self.owner)

    def getOwner(self):
        return self.owner

ここでは具体的処理を定義している。このクラスはProductクラスのサブクラスとして定義して、コンストラクタを作り、
useメソッドとgetOwnerメソッドを定義。
さらにIDCardFactoryクラス

class IDCardFactory(Factory):
    owners = []
    def createProduct(self, owner):
        return IDCard(owner)

    def registerProduct(self, product):
        self.owners.append(product.getOwner())

    def getOwners(self):
        return owners

このクラスでcreateProductとregisterProductメソッドを実装している。
createProductメソッドはIDCardクラスのインスタンスを生成して「製品を作る」を行っている。
registerProductメソッドはgetOwnerメソッドで得たIDCardのowner(所有者)をリストownersに加えることで
「登録」を行っている。
最後に動作テストを行う部分

factory = IDCardFactory()
card1 = factory.create("Taro")
card2 = factory.create("Ichiro")
card3 = factory.create("Hanako")
card1.use()
card2.use()
card3.use()

IDCardFactoryクラスのインスタンスを作って、createメソッドを使う。IDCardFactoryクラスはFactoryクラスの
サブクラスだからcreateメソッドが使える。createメソッドは「製品」のインスタンスを生成するので、そのインスタンス
対してuseメソッドを使う。IDCardFactoryクラスのインスタンスはIDCardクラスのインスタンスを生成するのでIDCardクラス
で実装されているuseメソッドを適用できることになる。
実際に実行してみると、

C:\works\python\book1>python factory_method.py
make Taro's card
make Ichiro's card
make Hanako's card
use Taro's card
use Ichiro's card
use Hanako's card

インスタンス生成による委譲を利用してTemplate Methodパターンを実現したパターンになるわけか。