woshidan's loose leaf

ぼんやり勉強しています。

Template Methodパターン

テンプレートパターン、実はファクトリーパターンとの区別がちゃんとついていなかったりする。 というより、Template Methodパターンなのですね(え)。

サブクラスがいくつかのメソッドを持っていることを前提に、 スーパークラス(抽象クラス)でそれらのメソッドを使った処理を書く(処理の枠組みを定める、という言葉が使われている)。

スーパークラスでは空でもいいので、それらのメソッドを定義しておくこと。

そうすると、そのスーパークラスを継承したクラスで行う処理の流れは統一されているから理解しやすく、 サブクラス側を見ると、処理の詳細の差分のメソッドだけを書けば良いので、同じ系統のクラスとの差が把握しやすい、のかな。

スーパークラスをAbstractClass、サブクラスをConcreteClassと呼ぶ。

同じ処理を行う、同じ系統のクラスは、1つのクラスやモジュールの下位クラスにして、 共通する処理は括り出していきましょうよ、という話。

なんとなく、Rubyメソッドでブロックを引数に取った時の動きに、 ブロックがサブクラスのメソッドで、ブロックを引数に取るメソッドスーパークラスみたいだな、 と思ったのですが、Rubyを始めて一年3ヶ月ほどで、 そういった処理は書いた事がないので気のせいでしょう。

何が嬉しいんでしょう。と思っていたのですが、最近格闘しているクラスが、 Template Methodパターンを適用した方がよさそうな事例だったので、 その兆候などのメモを置いておきます。

  • 変数に代入する値の取得方法が違うだけ、など条件分岐した処理で変化する値の形式が一緒か、ほぼ一緒
  • 条件分岐した場合の処理が何度か登場してしまうのでメソッドに押し込めている
  • 上記のメソッドを順に呼び出すためのメソッドが数種類1つのクラスに転がっている
    • 詳細のメソッドを呼び出すメソッドスーパークラスか、モジュール(AbstractClass)に持たせる
    • 条件分岐部分の処理はサブクラスかモジュールをインクルードするクラスに持たせる
      • クラスの責務が「処理の流れを決める」「処理の詳細を決める」に別れてはっきりする
      • 経験上、「処理の流れを決める」クラスを1つ置くと、同じ構成のコードが数百行続いて辛い事態が防げる

なんていうか、いま条件分岐で分けたり追加している部分は多分クラスに分けて、
今日メソッドに括り出した部分はモジュールにまで出した方が最終的に見通しはいいんだけど、
全部いじってると趣味に近くなるし、レビュアーはがっつり読まないといけないので、大変なんだよな...