Template Methodパターン

2020/10/15 15:00

GoFデザインパターンのTemplate Methodパターンをコードで理解します。似たような流れの処理を共通化したい時に「親クラスで基本の流れを書いておき、子クラスで詳細な内容を実装する」という形で実現します。継承を用いて共通化を進めると良く出てくる形です。12分の動画です。

Template Methodパターンとは

基本的には同じ流れで処理できる複数のクラスがある場合、それらの親クラス(Abstract Class)で流れを定義しておき(流れを定義しているメソッドをテンプレートメソッドと呼びます)、子クラス(Concrete Class)で処理の内容を実装もしくはオーバーライドすることで上手く共通化します。

特に「いくつかのデフォルトの動きがあるが、ある場合には変更したりする」など微妙な差異のクラスが多い場合には見通しがよくなります。「基本の流れはこれ」と親クラスで理解すれば、あとはどの部分が変更された亜種なのかを子クラスの差分を見るだけで良い為です。

継承を利用するとこの形になりがちなので、あまり意識せずに使っている人も多いと思います。

変異

  • 動画では親クラスには抽象メソッド群しか無いような説明でしたが、デフォルトの処理を入れておくような形もよくあります。
  • 継承での実装は大抵コンポジションでの実装で置き換えられるので、抽象メソッド群の部分をインターフェースとして定義して、外から渡してやるような別の構造の実装も考える事ができます。このことからStrategyパターンとの類似性が見られます。

デメリット

  • 基本の流れ自体が違うクラスが出てきた場合に、親クラス側にあるロジックが邪魔になるケースがあります。そういう場合に親クラスにあるテンプレートメソッドをオーバーライドしても良いかもしれませんが、多用すると見通しが悪くなってしまいます。
  • 上記を回避するのに、親クラスの動きをインターフェースで先に用意しておき、本パターンを適用する実装としない実装を提供できるようにする事は柔軟性を高める意味で良い事だと思います。
  • 亜種の処理の数分子クラスができるので、場合によっては管理が複雑になるでしょう(大抵はifを減らす方が嬉しいのでこれがクリティカルなデメリットになる事は少ないと思いますが)

解説に利用したコード ~ Sample code ~

https://github.com/CircleAround/pgonline/blob/master/src/20200926templatemethod.ts

この記事を書いた人

佐藤 正志

サークルアラウンド株式会社 代表取締役