デザインパターン:Template Method(テンプレートメソッド)パターン
Template Methodパターンとは
- Template Methodパターンは、テンプレートの機能を持つパターンです。
- スーパークラスの方にテンプレートとなるメソッドが定義されています。
- その定義の中では抽象メソッドが使われています。
- このため、スーパークラスのプログラムを読んでいるだけでは、最終的にどんな処理をすることになるかは分かりません。
- わかることは、抽象メソッドをどのように呼び出しているか、ということだけです。
- 抽象メソッドを実際に実装するのはサブクラスです。
- サブクラスの側でメソッドを実装すれば、具体的な処理が決定します。
- 異なるサブクラスが異なる実装を行えば、異なる処理が行われます。
- しかし、どのサブクラスでどのような実装をしたとしても、処理の大きな流れはスーパークラスで組み立てたとおりになります。
- このように、スーパークラスで処理の枠組みを定め、サブクラスでその具体的な内容を定めるようなデザインパターンを、「Template Methodパターン」と呼びます。
Template Methodパターンを使うメリットについて
ロジックが共通化できる
- スーパークラスのテンプレートメソッドでアルゴリズムが記述されているので、サブクラス側ではアルゴリズムをいちいち記述する必要がなくなります。
- もし、Template Methodパターンを使わず、複数のクラスにロジック部分をコピペしていると、バグが発見されたときに、ロジックが書かれているすべてのクラスを修正しなければならなくなります。
Template Methodパターンでプログラミングしていれば、テンプレートメソッドに誤りが発見された場合は、テンプレートメソッドのみ修正すればよいことになります。
サンプルプログラム
クラス一覧
名前 | 説明 |
---|---|
Shopping.java | メソッドtoShoppingのみ実装されている抽象クラス |
OnlineShop.java | メソッドchooseProduct, goToCashRegister, Payを実装しているクラス |
RealStore.java | メソッドchooseProduct, goToCashRegister, Payを実装しているクラス |
Main.java | 動作テスト用のクラス |
クラス図
Shopping.java
public abstract class Shopping { public abstract void chooseProduct(); public abstract void goToCashRegister(); public abstract void pay(); public void toShopping() { chooseProduct(); goToCashRegister(); pay(); } }
RealStore.java
public class RealStore extends Shopping { private String product; public RealStore(String product) { this.product = product; } @Override public void chooseProduct() { System.out.println("***リアル店舗でお買い物***\n"); System.out.println("陳列棚から「" + product + "」を選びました。"); } @Override public void goToCashRegister() { System.out.println("レジに並びます。\n人が少ない列に並びました。"); } @Override public void pay() { System.out.println("端末に電子マネーのカードをかざして支払いをしました。\n"); } }
OnlineShop.java
public class OnlineShop extends Shopping { private String product; public OnlineShop (String product) { this.product = product; } @Override public void chooseProduct() { System.out.println("***ネットショッピング***\n"); System.out.println("商品リストから「" + product + "」を選びました。"); } @Override public void goToCashRegister() { System.out.println("レジへ行くボタンを押下しました。"); } @Override public void pay() { System.out.println("クレジットカードで支払いをしました。\n"); } }
Main.java
public class Main { public static void main(String[] args) { Shopping sh1 = new RealStore("アイスクリーム"); Shopping sh2 = new OnlineShop("地方の名産品"); sh1.toShopping(); sh2.toShopping(); } }
実行結果
***リアル店舗でお買い物*** 陳列棚から「アイスクリーム」を選びました。 レジに並びます。 人が少ない列に並びました。 端末に電子マネーのカードをかざして支払いをしました。 ***ネットショッピング*** 商品リストから「地方の名産品」を選びました。 レジへ行くボタンを押下しました。 クレジットカードで支払いをしました。
参考:詳しくは、以下の書籍を参照してください
- 「補講:クラス階層と抽象クラス」も参考になります
- 練習問題もあります