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パターンを実現したパターンになるわけか。