search
LoginSignup
0

More than 3 years have passed since last update.

posted at

updated at

JavaでTemplateMethodパターン

はじめに

GoFのデザインパターンを紹介している『増補改訂版 Java言語で学ぶデザインパターン入門』を読んで、学んだ内容についてまとめます。

TemplateMethodパターン

TemplateMethodとは

処理の骨組みをスーパークラスで定義し、具体的な実装についてはサブクラスで定義するパターンのことTemplateMethodパターンと言います。
この内、スーパークラスで「処理の骨組みを定義しているメソッド」がTemplateMethodになります。

登場人物

TemplateMethodパターンで使用するのは以下のクラス図に登場するクラスです。
image.png

抽象クラス

  • AbstractClass
    テンプレートメソッドを実装するクラスです。
    テンプレートメソッド内で呼び出すメソッドについても宣言を行いますが、実装についてはサブクラスのConcreateClassで行います。
    そのため、テンプレートメソッド以外のメソッドは抽象メソッドとなります。

実装クラス

  • ConcreateClass
    テンプレートメソッド内で呼び出されている抽象メソッドを実装するクラスです。
    ここで実装したメソッドがスーパークラスであるAbstractClassから呼び出されます。

具体例

具体例として、「手順書」と「作業Aの手順書」、「作業Bの手順書」をもとに説明します。

抽象クラス

  • AbstractManualクラス
    AbstractManual(手順書)クラスは抽象クラスで、作業手順の骨組みを実装します。
    ここではoperation()メソッドが作業手順の骨組みを実装しているメソッド(templateMethod)になります。
    その他のstart()メソッド、work()メソッド、end()メソッドに関しては宣言を行い、operation()メソッド内で呼び出しを行なっていますが、実装は行なっておらず、具体的な処理についてはサブクラスのOperationAManual.classOperationBManual.classで定義します。
AbstractManual.java
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()メソッドで出力を行っています。
OperationAManual.java
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()メソッドで出力を行っています。
OperationBManual.java
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クラス
    OperationAManualOperationBManualのインスタンスを生成し、TemplateMethodのoperation()を呼び出しています。
Main.java
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パターンに関して学びました。
以下でサンプルコードをアップしていますのでよろしければ参考にどうぞ。

また、他のデザインパターンに関しては以下でまとめていますので、こちらも参考にどうぞ。

参考文献

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
0