なぜこの記事を書いたのか
こんにちは。私は、@terada1228 と申します。
普段は EC サイトを運営する会社でサーバサイドエンジニアをしております。
現在エンジニアとして働いて1年半ほど経ちましたが、自身のスキルをもう一段階上にするため、デザインパターンの学習を進めているところです。
デザインパターンを学ぶ内に、各パターンを見ているとその中で他のパターンが使用されていることに気づきます。
その中でもテンプレートメソッドパターンは特に登場することの多いデザインパターンの1つです。
あらゆるデザインパターンの基礎とも言えるテンプレートメソッドパターンについて、今回は記事にまとめてみました。
なお、この記事はとても有名な、Java 言語で学ぶデザインパターン入門を参考にしております。さらに深く知りたいという方はぜひ購入してみてください。
増補改訂版 Java言語で学ぶデザインパターン入門【電子書籍】[ 結城 浩 ] 価格:4180円 (2021/12/14時点)楽天で購入 |
テンプレートメソッドパターンとは何か
テンプレートメソッドとは、内部で抽象メソッドを呼んでいるメソッドのことです。
抽象メソッドを呼ぶということは、現時点ではそのメソッドの中身が分からないということです。要するに最終的にどのような処理がされるのかはわかりません。
この段階でわかることは、どの抽象メソッドをどういった形で呼び出すか、ということだけです。
言葉だけだとちょっと何を言っているのか分からないですよね。実際にコードを見ていきましょう。
サンプルコードを見てみる
今回のサンプルコードですが、画面に文字を出力するためのプログラムを考えていきます。
ただ、文字の出力は2通りの方法を実現したいです。
まず1つめは、文字を受け取って画面に出力する です。
例えば、H
という文字を受け取ったら、画面には以下のように出力されます。
<<HHHHH>>
そして2つ目は、文字列を受け取って画面に出力するです。
こちらでは、Hello, World.
という文字列を受け取った場合を例にすると、以下のように出力されます。
+-------------+
|Hello, world.|
|Hello, world.|
|Hello, world.|
|Hello, world.|
|Hello, world.|
+-------------+
この2つ、出力自体は大きく異なるように見えますが、処理を分解してみると共通して実行される処理がありそうですね。
- 最初に特定のフォーマットの文字列を出力する
- 1 なら、
<<
。2 では+-----+
を出力。
- 1 なら、
- 与えられた文字、または文字列を出力する
- 最後にまた特定のフォーマットの文字列を出力する
- 1 なら、
>>
。2 では+-----+
を出力。
- 1 なら、
このような要件に対してはテンプレートメソッドパターンが有効です。
早速サンプルコードの方を見ていきましょう。
このアプリケーションは以下のようなクラス図で表されるものになります。
まずは AbstractDisplay
から見ていきます。
AbstractDisplay
は display
という名前のテンプレートメソッドを定義するクラスになります。
テンプレートメソッドの中でコールされる、open
, print
, close
は抽象メソッドになっていて、この時点ではどのような処理がされるか不明です。
これらの実装は、AbstractDisplay
を継承する、CharDisplay
, StringDisplay
に任せられます。
CharDisplay
は 文字を受け取って画面に出力する ためのクラスです。
open
メソッドで、<<
を出力し、print
で文字の表示、close
で >>
を表示するよう、インタフェースを具体的に実装していきます。
次に、StringDisplay
は 文字列を受け取って画面に出力する ためのクラスです。
CharDisplay
と同様のインタフェースの実装を行なっていきますが、実装内容は異なります。
open
メソッドで +----+
を出力し、 print
で文字列の出力、 close
で +----+
を出力します。
これで用意すべきクラスは完成しました。実際に Main
クラスからこれらを実行していきます。
これを実行すると、要件を満たすような以下の出力を得ることができます。
<<HHHHH>>
+-------------+
|Hello, world.|
|Hello, world.|
|Hello, world.|
|Hello, world.|
|Hello, world.|
+-------------+
テンプレートメソッドパターンのメリット
ロジックを共通化できる
テンプレートメソッドでは、処理の詳細は決まりませんが、処理の流れはそこで記載されることになります。
サブクラスでは、その制約の元で抽象メソッドを実装していくことになるわけです。
そうすることで、サブクラスが増えていったとしても迷いなくコーディングができるので、アプリケーション全体として統一感のあるソースコードになります。
このことで保守性が向上するため、全くアプリケーションのことがわからない新規メンバーであっても簡単に機能改善 / 新規機能の追加ができることでしょう。
おわりに
デザインパターンはまさにツールで、例えば大工で言うところのノミやカンナといったところです。
ツールがたくさんあれば、その時々で最も適切な行動を取れる可能性が高まります。
今後も自身の理解を深めるためにも、少しづつデザインパターンの記事を出していければと考えています。お付き合いいただけましたら幸いです。
コメント