Java におけるテンプレートメソッドデザインパターン
テンプレートメソッドは、行動デザインパターンです。テンプレートメソッドデザインパターンは、メソッドのスタブを作成し、実装の一部をサブクラスに委任するために使用されます。
テンプレートメソッドデザインパターン
テンプレートメソッドは、アルゴリズムを実行する手順を定義し、それをすべてまたは一部のサブクラスに共通するデフォルトの実装を提供することができます。例を挙げてこのパターンを理解しましょう。例えば、家を建てるアルゴリズムを提供したいとします。家を建てるために実行する必要のある手順は、基礎を作る、柱を建てる、壁や窓を建てる、です。重要な点は、実行の順序を変更することができないということです。なぜなら、基礎を作らないと窓を建てることはできないからです。そのため、この場合、家を建てるために異なるメソッドを使用するテンプレートメソッドを作成することができます。家の基礎を作ることは、木造の家であろうと、ガラス造りの家であろうと、同じです。そのため、これに対して基本的な実装を提供することができます。サブクラスがこのメソッドをオーバーライドする場合は可能ですが、ほとんどの場合はすべての種類の家に共通です。テンプレートメソッドをサブクラスがオーバーライドしないようにするために、それをfinalにする必要があります。
テンプレートメソッドの抽象クラス
サブクラスによって実装されるいくつかのメソッドを必要とするため、基底クラスを抽象クラスとして作成する必要があります。HouseTemplate.java
package com.scdev.design.template;
public abstract class HouseTemplate {
//template method, final so subclasses can't override
public final void buildHouse(){
buildFoundation();
buildPillars();
buildWalls();
buildWindows();
System.out.println("House is built.");
}
//default implementation
private void buildWindows() {
System.out.println("Building Glass Windows");
}
//methods to be implemented by subclasses
public abstract void buildWalls();
public abstract void buildPillars();
private void buildFoundation() {
System.out.println("Building foundation with cement,iron rods and sand");
}
}
buildHouse()はテンプレートメソッドであり、複数の手順を実行するための順序を定義します。
テンプレートメソッドの具体クラス (Tenpureto mesoddo no gutaikurasu)
私たちは、木の家やガラスの家のように、さまざまな種類の家を持つことができます。WoodenHouse.java
package com.scdev.design.template;
public class WoodenHouse extends HouseTemplate {
@Override
public void buildWalls() {
System.out.println("Building Wooden Walls");
}
@Override
public void buildPillars() {
System.out.println("Building Pillars with Wood coating");
}
}
私たちは他のメソッドもオーバーライドすることができましたが、シンプルさのために行っていません。GlassHouse.java
package com.scdev.design.template;
public class GlassHouse extends HouseTemplate {
@Override
public void buildWalls() {
System.out.println("Building Glass Walls");
}
@Override
public void buildPillars() {
System.out.println("Building Pillars with glass coating");
}
}
テンプレートメソッドデザインパターンのクライアント
テンプレートメソッドパターンの例をテストプログラムを使って確認しましょう。HousingClient.java
package com.scdev.design.template;
public class HousingClient {
public static void main(String[] args) {
HouseTemplate houseType = new WoodenHouse();
//using template method
houseType.buildHouse();
System.out.println("************");
houseType = new GlassHouse();
houseType.buildHouse();
}
}
クライアントがベースクラスのテンプレートメソッドを呼び出し、異なるステップの実装に応じて、ベースクラスとサブクラスの一部のメソッドを使用しています。上記のプログラムの出力は次のとおりです。
Building foundation with cement,iron rods and sand
Building Pillars with Wood coating
Building Wooden Walls
Building Glass Windows
House is built.
************
Building foundation with cement,iron rods and sand
Building Pillars with glass coating
Building Glass Walls
Building Glass Windows
House is built.
テンプレートメソッドのクラスダイアグラム
JDKにおけるテンプレートメソッドデザインパターン
- All non-abstract methods of java.io.InputStream, java.io.OutputStream, java.io.Reader and java.io.Writer.
- All non-abstract methods of java.util.AbstractList, java.util.AbstractSet and java.util.AbstractMap.
テンプレートメソッドデザインパターンの重要なポイント
-
- テンプレートメソッドは、順序が固定されている特定の手順で構成され、いくつかのメソッドの実装は基底クラスから派生クラスまで異なります。テンプレートメソッドは最終的であるべきです。
-
- ほとんどの場合、サブクラスはスーパークラスのメソッドを呼び出しますが、テンプレートパターンでは、スーパークラスのテンプレートメソッドがサブクラスのメソッドを呼び出すため、「呼び出しは私たちに任せてください」という考え方があります。これはハリウッドの原則として知られています。
- 基本クラスのデフォルトの実装を持つメソッドはフックと呼ばれ、サブクラスによってオーバーライドすることが意図されています。一部のメソッドをオーバーライドしないようにする場合は、それらを最終的にすることができます。たとえば、私たちの場合ではbuildFoundation()メソッドを最終的にすることができます。
これでJavaのテンプレートメソッドデザインパターンに関する説明は終わりです。お気に入りいただけたことを願っています。