Pythonでデザインパターン 参ノ型「TemplateMethod」
今回はPythonの勉強しながらデザインパターンのTemplateMethodをやってみました。
他のパターンにつきましては、以下の目次記事をご参照ください。
TemplateMethodとは
直訳すると「型板手続き」みたいな意味になります。
wikiには「ある処理のおおまかなアルゴリズムをあらかじめ決めておいて、そのアルゴリズムの具体的な設計をサブクラスに任せること」とあります。
TemplateMethodについて考えてみる
TemplateMethodパターンは抽象クラスを使用することで実現することができます。
いつもどおり、ざっくりした例で説明してみます。
以下はテンプレートクラス:Templateです。
このクラスではinterfaceA()、interfaceB()、interfaceC()というインタフェースがあります。
また、methodA()というメソッドがあり、このメソッドではinterfaceA()、interfaceB()、interfaceC()を順番に呼び出しています。
これがテンプレートメソッドとなります。
class Template(metaclass=ABCMeta) : @abstractmethod def _interfaceA(self) : pass @abstractmethod def _interfaceB(self) : pass @abstractmethod def _interfaceC(self) : pass def methodA(self) : self._interfaceA() self._interfaceB() self._interfaceC()
そして以下がTemplateクラスを継承した実体クラス:Hogeです。
このクラスではTemplateクラスのinterfaceA()、interfaceB()、interfaceC()をオーバライドして実装しています。
処理内容は割愛で(;^ω^)
class Hoge(Template) : def _interfaceA(self) : # 処理A def _interfaceB(self) : # 処理B def _interfaceC(self) : # 処理C
最後にHogeクラスを使用するmainの例です。
この例ではHogeクラスのインスタンスを作成して、methodA()を呼び出しています。
if __name__ == '__main__' : hogo = Hogo() hogo.methodA() # interfaceA, B, Cが順番に呼び出される
HogeクラスはTemplateクラスを継承しているので、TemplateクラスのmethodA()が呼び出されます。
したがってHogeクラスで実装したinterfaceA()、interfaceB()、interfaceC()が順番に呼び出されます。
この例をwikiの言葉を借りてまとめると、
methodA()のように、「ある処理のおおまかなアルゴリズムをあらかじめ決めておいて」、
interfaceA()、interfaceB()、interfaceC()のように、別クラスで実装することで「そのアルゴリズムの具体的な設計をサブクラスに任せる」
という感じがTemplateMethodパターンとなります(・`ω´・)
サンプルプログラム
以下、サンプルプログラムです。
AbstractDisplayクラスがテンプレートクラス、displey()がテンプレートメソッドになります。
そしてCharDisplayとStringDisplayクラスがAbstractDisplayクラスを継承した実体クラスです。
CharDisplayは1文字、StringDisplayは文字列をdispley()で指定したように表示するようになっています。
そのために、それぞれAbstractDisplayクラスのインタフェースであるmyOpen()、myPrint()、myClose()をオーバライドして実装しています。
CharDisplayクラスのmyOpen()、myClose()は"***"、myPrint()ではコンストラクタで指定された文字を表示するようになっています。
またStringDisplayクラスではmyClose()は"---"、myPrint()ではコンストラクタで指定された文字列を表示するようになっています。
# coding: utf-8 from abc import ABC, ABCMeta, abstractmethod class AbstractDisplay(metaclass=ABCMeta) : @abstractmethod def myOpen(self) : pass @abstractmethod def myPrint(self) : pass @abstractmethod def myClose(self) : pass def displey(self) : self.myOpen() for i in range(3) : self.myPrint() self.myClose() class CharDisplay(AbstractDisplay) : def __init__(self, ch) : self.__ch = ch def myOpen(self) : print("***") def myPrint(self) : print(self.__ch) def myClose(self) : print("***") class StringDisplay(AbstractDisplay) : def __init__(self, str) : self.__str = str def myOpen(self) : print("---") def myPrint(self) : print(self.__str) def myClose(self) : print("---") if __name__ == '__main__' : cd = CharDisplay('T') sd = StringDisplay("Design Pattern") sd2 = StringDisplay("Template Method") cd.displey() sd.displey() sd2.displey()
実行結果は以下になります!
CharDisplayのdispley()とStringDisplayで表示結果は異なるけれど(myOpen()、myPrint()、myClose()の実装は異なるけれど)、アルゴリズムは同じ(displey()でmyOpen()、myPrint()、myClose()を使用する手順は同じ)であるとわかります(・`ω´・)v
$ python TemplateMethod.py *** T T T *** --- Design Pattern Design Pattern Design Pattern --- --- Template Method Template Method Template Method ---
- 価格: 2860 円
- 楽天で詳細を見る