Template Methodパターン
アルゴリズムの骨組みを定義し、一部のステップをサブクラスに委譲する仕組みを提供するデザインパターン。
このパターンは、同じ大枠のアルゴリズムは共有するが、いくつかのステップが具体的なサブクラスで異なる場合に特に有用。
アルゴリズムの構造を定義し、具体的なステップの実装をサブクラスに任せる。
オブジェクトライフサイクル管理や、データの処理アルゴリズム、ウィンドウの表示、ドキュメントの保存、データベースへの接続などに利用される。
Template Methodパターンが利用できるシチュエーション
Step 1、Step 2 という処理から構成される2種類の手順アルゴリズム Process 1、Process 2 があるものとする。
Step1 は共通の処理。
Step 2 はそれぞれ別々の処理を行わせたい。
さらに、Process 2 では Step 2 の実行後に別の処理も実行させたい。
必要な抽象クラス
Step 1 は共通の処理であるため、コードの重複をさせないように抽象クラスで定義する。
さらに、抽象クラスにはフックと呼ばれるメソッドhook()を用意する。
フックは、何もしない空の関数もしくはデフォルト処理を行う関数であるが、必要な時だけサブクラスにオーバーライドさせ、特定の処理を実行させることができる。(必要でない時は、オーバーライドしなくて良い)
それぞれ独自の処理については、サブクラスに委譲する。
public abstract class Process {
// アルゴリズムの骨組みが定義された Template Method
public void execute() {
commonStep1();
originalStep2();
hook();
}
// 共通の処理
// final でオーバーライドさせないようにもできる
final void commonStep1() {
System.out.println("共通の処理 Step1 を実行します。");
}
// サブクラスに委譲
abstract void originalStep2();
// フック
void hook() {}
}
抽象クラスの継承
// Process 1
public class Process1 extends Process
{
// 独自の処理
@Override
void originalStep2() {
System.out.println("Process 1 の独自処理です。");
}
// hook() はオーバーライドしない
}
// Process 2
public class Process2 extends Process {
// 独自の処理
@Override
void originalStep2() {
System.out.println("Process 2 の独自処理です。");
}
// hook() に処理を加える
@Override
void hook(){
System.out.println("Process 2 では、ここで何らかの処理を行います。");
}
}
Template Methodパターンの利用
public class Main {
public static void main(String[] args){
// Process 1
Process process1 = new Process1();
process1.execute();
// >> 共通の処理 Step1 を実行します。
// >> Process 1 の独自処理です。
// Process 2
Process process2 = new Process2();
process2.execute();
// >> 共通の処理 Step1 を実行します。
// >> Process 2 の独自処理です。
// >> Process 2 では、ここで何らかの処理を行います。
}
}
