pythonによるデザインパターン[template method]

# Intro

この文章は結城 浩さんの「Java言語で学ぶデザインパターン入門」を、pythonで実装してみたサンプルコードです。

筆者の環境は以下の通りです。Python 3.6.3

まだ修行中の身なので間違いがあると思いますがご了承ください。 今回は「Template Method」です

# Explanation

本書のp33によると、 template methodとは

スーパークラスで処理の枠組みを定め、サブクラスでその具体的内容を定めるようなデザインパターン

とあります。その通り、スーパークラスを定義し、共通部分をくくり出すという感じです。

pythonでは言語仕様として抽象クラス・抽象メソッドが存在するので、それを適切に利用すれば良いと言った感じでしょうか。

# Practice

## Specification
文字(列)を入力すると

<<字字字字字>>

と表示する、もしくは

+ — — — — — — — — — — — — +
|(ここに文字列が入ります)|
|(ここに文字列が入ります)|
|(ここに文字列が入ります)|
|(ここに文字列が入ります)|
|(ここに文字列が入ります)|
+ — — — — — — — — — — — — +

と表示するようなコード。

どちらのフォーマットも同じ文字(列)を5回繰り返しているので、

  • 何かを表示する(+ — — — — — — — — — — — — +or<<)
  • 文字(列)を5回表示する
  • 何かを表示する(+ — — — — — — — — — — — — +or>>)
    の一連の流れを抽象クラス(class AbstractDisplay)の抽象メソッド(def display)にまとめます。

その上で、上のフォーマットの場合は

  • <<を表示する
  • 文字を5回表示する
  • >>を表示する
    を実現するclass(class CharDisplay)を,

下のフォーマットの場合は

  • + — — — — — — — — — — — — +を表示する
  • 文字(列)を5回表示する
  • + — — — — — — — — — — — — +を表示する
    を実現するclass(class StringDisplay)を作成します。

## sample code

## Explanation

まず抽象クラスであるAbstractDisplayを作成します。

抽象クラスなので(metaclass=ABCMeta)を忘れないように。

そのクラスに、それぞれの処理を

  • 何かを表示するdef open
  • 文字(列)を表示するdef pprint
  • 何かを表示するdef close

のようにメソッドにまとめます。

そして、def displayクラスで

def open->def pprintを5回呼び出し->def close

の流れを記述します。

重要なのが、抽象クラスでは、全体の流れを決定するdef displayは普通のメソッドですが、それぞれの処理は抽象メソッドで定義します。

それぞれの処理は空(pass)でいいのですが、抽象メソッド(@abstractmethod)とするのを忘れないようにしてください。

各フォーマットのclassでは、抽象クラス(AbstractDisplay)を継承し、def open,def pprint,def closeのそれぞれの中身を記述していきます。

# Conclustion

冒頭で言った通り、pythonは言語仕様で抽象クラスをサポートしているので、デザインパターンの学習というよりもpythonの抽象クラスの学習といった感じがしました。

抽象クラスを使うことはできても、適切にクラスを分解するのは意外と難しいのでしっかり設計して、その上でtemplate methodを使っていきたいですね。

# ref

--

--