はじめに
GoFのデザインパターンを紹介している『増補改訂版 Java言語で学ぶデザインパターン入門』を読んで、学んだ内容についてまとめます。
TemplateMethodパターン
TemplateMethodとは
処理の骨組みをスーパークラスで定義し、具体的な実装についてはサブクラスで定義するパターンのことをTemplateMethodパターンと言います。
この内、スーパークラスで「処理の骨組みを定義しているメソッド」がTemplateMethodになります。
登場人物
TemplateMethodパターンで使用するのは以下のクラス図に登場するクラスです。
抽象クラス
-
AbstractClass
テンプレートメソッドを実装するクラスです。
テンプレートメソッド内で呼び出すメソッドについても宣言を行いますが、実装についてはサブクラスのConcreateClass
で行います。
そのため、テンプレートメソッド以外のメソッドは抽象メソッドとなります。
実装クラス
-
ConcreateClass
テンプレートメソッド内で呼び出されている抽象メソッドを実装するクラスです。
ここで実装したメソッドがスーパークラスであるAbstractClass
から呼び出されます。
具体例
具体例として、「手順書」と「作業Aの手順書」、「作業Bの手順書」をもとに説明します。
抽象クラス
-
AbstractManualクラス
AbstractManual(手順書)クラスは抽象クラスで、作業手順の骨組みを実装します。
ここでは**operation()
メソッド**が作業手順の骨組みを実装しているメソッド(templateMethod)になります。
その他のstart()
メソッド、work()
メソッド、end()
メソッドに関しては宣言を行い、operation()
メソッド内で呼び出しを行なっていますが、実装は行なっておらず、具体的な処理についてはサブクラスのOperationAManual.class
とOperationBManual.class
で定義します。
package templateMethod;
public abstract class AbstractManual{
public abstract void start();
public abstract void work();
public abstract void end();
public final void operation() {
start();
for (int i = 0; i < 3; i++) {
work();
}
end();
}
}
実装クラス
-
OperationAManualクラス
抽象メソッドのstart()
、work()
、end()
を実装しています。
コンストラクタで文字を受け取りwork()
メソッドで出力を行っています。
package templateMethod;
public class OperationAManual extends AbstractManual {
private char ch;
public OperationAManual(char ch) {
this.ch = ch;
}
@Override
public void start() {
System.out.println("<<作業A開始>>");
}
@Override
public void work() {
System.out.println(ch + "を処理しています");
}
@Override
public void end() {
System.out.println("<<作業A終了>>");
}
}
-
OperationBManualクラス
OperationAManual.class
と同様に抽象メソッドのstart()
、work()
、end()
を実装していますが、実装の内容については異なっています。
コンストラクタで文字列を受け取り、work()
メソッドで出力を行っています。
package templateMethod;
public class OperationBManual extends AbstractManual {
private String string;
public OperationBManual(String string) {
this.string = string;
}
@Override
public void start() {
System.out.println("**作業B開始**");
}
@Override
public void work() {
System.out.println(string + "を処理しています");
}
@Override
public void end() {
System.out.println("**作業B終了**");
}
}
実行クラス
-
Mainクラス
OperationAManual
とOperationBManual
のインスタンスを生成し、TemplateMethodのoperation()
を呼び出しています。
package templateMethod;
public class Main {
public static void main(String[] args) {
AbstractManual d1 = new OperationAManual('F');
AbstractManual d2 = new OperationBManual("HelloWorld");
d1.operation();
d2.operation();
}
}
実行結果
Main.java
を実行した結果は以下になります。
同様のoperation()
を呼び出しましたが、異なる出力がされていることが確認できます。
<<作業A開始>>
Fを処理しています
Fを処理しています
Fを処理しています
<<作業A終了>>
**作業B開始**
HelloWorldを処理しています
HelloWorldを処理しています
HelloWorldを処理しています
**作業B終了**
メリット
TemplateMethodパターンを活用することで、処理の骨組みを共通化できます。
このようにすることで複数の作業者が各々好き勝手に処理の骨組みから作成を行い、一律にすべき部分が一律になっていない、ということが防げます。
まとめ
処理の骨組みを規定するTemplateMethodパターンに関して学びました。
以下でサンプルコードをアップしていますのでよろしければ参考にどうぞ。
また、他のデザインパターンに関しては以下でまとめていますので、こちらも参考にどうぞ。