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
- 「増補改訂版 Java言語で学ぶデザインパターン入門」 結城浩(著)第11版
- 「29.7. abc — Abstract Base Classes — Python 3.6.4 documentation」 閲覧日 2018/01/02