2010年5月2日日曜日

Template Methodパターン

Template Methodパターンとは、文字通り、テンプレートとなるメソッドを用意して利用するパターンです。具体的には、内部に抽象メソッド(Javaの場合、abstractをつけたメソッド)をいくつか呼び出しているテンプレートメソッドを用意し、、抽象メソッドの具体的な処理をサブクラスで決めます。もちろん、サブクラスによって抽象メソッドの処理内容は違う可能性があるわけですが、どのように実装しても大きな流れはテンプレートメソッドで組み立てた通りになります。

例えば、テンプレートのあるクラスは
  1. public abstract class AbstractSample {  
  2.     protected abstract void start();  
  3.     protected abstract void finish();  
  4.     public final void execute() {  
  5.         start();  
  6.         System.out.println("execute");  
  7.         finish();  
  8.     }  
  9. }  

になります。execute()がテンプレートメソッドです。start()とfinishi()はサブクラスで以下のように定義します。
  1. public class Sample extends AbstractSample {  
  2.     protected void start() {  
  3.         System.out.println("--- Start ---");  
  4.     }  
  5.   
  6.     protected void finish() {  
  7.         System.out.println("--- Stop ---");  
  8.     }  
  9. }  

別のサブクラスでは以下のようにしてみます。
  1. public class AnotherSample extends AbstractSample {  
  2.     protected void start() {  
  3.         System.out.println("*** スタート ***");  
  4.     }  
  5.   
  6.     protected void finish() {  
  7.         System.out.println("*** 終了 ***");  
  8.     }  
  9. }  

Mainクラスは以下のようにしてみました。
  1. public class Main {  
  2.     public static void main(String[] args) {  
  3.         AbstractSample sample = new Sample();  
  4.         sample.execute();  
  5.         AbstractSample anotherSample = new AnotherSample();  
  6.         anotherSample.execute();  
  7.     }  
  8. }  

実行結果はこんな感じです。








このようにすることで、

  • サブクラスをいくつ作っても、大きな流れはテンプレートメソッドの通り(ロジック共通化)
  • サブクラスをいくつ作っても、呼び出すメソッドは同じ名前のメソッド

といった点が挙げられます。具体的な処理はサブクラスに決めてもらわないといけないとは言え、抽象クラスで処理を形作れることが、抽象クラスの存在意義と言えるでしょう。

注意:本に付属のサンプルコードで、Linux向けのものは文字コードがEUC_JPになっているため、コンパイル時に場合によっては警告が出るかもしれません。その時は、コンパイル時にencodingオプションを入れて

%> javac -encoding EUC_JP *.java

とすること。

関連パターン
「Factory Methodパターン」 Template Methodパターンをインスタンス生成に応用した例
Strategyパターン」Template Methodパターンでは継承を利用してプログラム動作を変更するのに対し、Strategyパターンでは移譲を利用してプログラム動作を変更する。

0 件のコメント:

コメントを投稿