今回紹介するTemplateパターンは比較的理解しやすいデザインパターンです。
タイトルにもあるように、「アルゴリズムだけを定義し、詳しい実装についてはサブクラスに任せる」ような仕組み、これがTemplateパターンです。
実際の例に当てはめるとTemplateパターンはいろいろな場面で現れます。
例えばお米を炊くといった動作もその一つです。
「米を研ぐ、炊く、蒸す」といった一連のアルゴリズムは決まっていますが、「ミネラルウォーターで研ぐか水道水で研ぐか」、「炊飯器か土鍋か」といった詳しい実装は実際に動作を行う人間に任されています。
では実際にどうプログラミングしていくか確認していきましょう。
Templateパターンとは
見出しでも記載しましたが、
- アルゴリズムだけを定義し、詳しい実装はサブクラスに委任する。
これが基本です。
実際にプログラミングする際にはスーパークラスにアルゴリズムを定義したtemplateMethodと、アルゴリズムで利用されるメソッドを抽象メソッドとして定義し、サブクラスに実装の責任を負わせます。
Templateパターンを理解するためには実際のコードを確認しながらのほうが分かりやすいかもしれません。
では実際にコーディングを行いましょう。
Templateパターンを実装してみよう。
見出しで記載した「炊飯」をコーディングします。
1 2 3 4 5 6 7 8 9 10 11 12 |
package com.xoxopigs.template; public abstract class CookRice { public abstract void sharpen(); // 研ぐ public abstract void cook(); // 炊飯 public abstract void steam(); // 蒸す public void cookingRice() { sharpen(); cook(); steam(); } } |
CookRiceクラスは抽象クラスと定義され、cookingRiceメソッドがアルゴリズムとして定義されています。
「研ぎ方、炊飯、蒸し方」は抽象メソッドとして、サブクラスに実装の責任を与えています。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
package com.xoxopigs.template; public class RiceCooker extends CookRice { public void sharpen() { System.out.println("研いだ"); } public void cook() { System.out.println("炊飯器を使いました"); } public void steam() { System.out.println("蓋を開けてしゃもじで軽く混ぜてみた"); } } |
ご飯を炊く方法に炊飯器を利用する場合は、研ぎ方、炊飯器での炊き方、蒸し方を実際に定義しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
package com.xoxopigs.template; public class EarthenPot extends CookRice { public void sharpen() { System.out.println("川水で研いだ"); } public void cook() { System.out.println("土鍋最高"); } public void steam() { // 土鍋組は何もしなかったようです。 } } |
こちらは土鍋組です。
炊飯器の場合と同じように各方法についての実装のみを定義しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
package com.xoxopigs.template; public class Main { public static void main(String args[]) { // 炊飯器組 CookRice cooker = new RiceCooker(); // 土鍋組 CookRice earthenPot = new EarthenPot(); System.out.println("* 炊飯器組:"); cooker.cookingRice(); System.out.println("\n* 土鍋組:"); earthenPot.cookingRice(); } } |
動作の実行確認です。
実際にサブクラスを利用する場合はアルゴリズムを呼び出すことで、炊飯器と土鍋どちらでもご飯を炊くことができますね。
出力は以下のようになります。
> * 炊飯器組:
> 研いだ
> 炊飯器を使いました
> 蓋を開けてしゃもじで軽く混ぜてみた
>
> * 土鍋組:
> 川水で研いだ
> 土鍋最高
クラス図
内容自体はとても簡単だったと思います。
繰り返すようですが、スーパークラスである[ AbstractClass ]でアルゴリズム( = templateMethod)を定義し、その中でサブクラスに任せたい詳しい実装を抽象メソッドとして宣言します。
サブクラスはスーパークラスによって宣言された抽象メソッドを各々実装することで、アルゴリズムから解放されるメリットが生まれます。
まとめ
Java入門の本などで抽象クラスや継承について書かれた部分で似たようなことがかかれているかと思います。
そのためデザインパターンといってもすんなり頭に入ってくるのではないでしょうか。
実際に設計する場合は、「詳しい実装(abstractMethod)をどのくらい細分化するか」の部分が難しく感じるかもしれません。
意識しながらコーディングして、このあたりのコツを掴めるようになるとよさそうです。