LoginSignup
0
0

More than 3 years have passed since last update.

【デザインパターン】Template Methodでロジックを共通化する

Posted at

はじめに

今年の頭からデザインパターン の勉強をはじめました。最近インプットが過剰になってきたと感じたので、勉強したことのアウトプットの場としてTemplate Methodのまとめを書かせていただきました。読者の参考になれば幸いです。また、間違いっているところや気になる点があればご指摘いただければ嬉しいです。

目次

  • TemplateMethodを使うと何がうれしいか?
  • クラス図
  • DisplayFigureクラス
  • Circleクラス
  • Squareクラス
  • 実際に動かしてみる
  • ロジックを変更してみる

Template Methodを使うと何がうれしいか?

Template Methodを使うことで共通の処理を一つにまとめることができ、あとでロジックを変更したいときに修正箇所を減らし、コードの保守性を高めることができます。この説明だけではわかりにくいと思うので、実際のプログラムで説明していきます。

クラス図

クラス図.png
抽象クラスDisplayFigureを継承したCircle、Squareがあります。MainクラスはDisplayFigureクラスを介して子クラスのメソッドを利用します。

DisplayFigureクラス

DisplayFigure.java
public abstract class  DisplayFigure {

    public  void init() {
        System.out.println("--  start!!  --");
    }

    public abstract void printFigure();

    public  void finish() {
        System.out.println("-- finish!!  --");
    }

    public void final display() {
        init();
        for(int i = 0; i < 5; i ++) {
            for(int j = 0; j <= i; j ++) {
                printFigure();
            }
            System.out.println();
        }
        finish();
    }
}


図形を表示する処理が実装されたクラスです。このクラスは抽象クラスで抽象メソッドprintFigure()を実装しており、子クラスに実装を強制しています。dispaly()では上の3つのメソッドをひとまとめにしており、子クラスでの処理を共通化しています。ここで重要なのがfinal修飾子でこの修飾子がついたメソッドは子クラスでオーバーライドして書き換えることができません。このメソッドをそのまま利用してくださいという意図が読み取れるのではないでしょうか?

Circleクラス

Circle.java
public class Circle extends DisplayFigure {

    private char symbol;

    public Circle(char symbol) {
        this.symbol = symbol;
    }

    public void  printFigure() {
        System.out.print(symbol);
    }
}

次にDisplayFigureクラスを継承したCircleクラスをみていきましょう。上位クラスで定義したprintFigure()の中身を実装しています。ロジックは親クラスに実装されているので比較的シンプルな実装になっています。クラス作成時点で初期化された変数symbplの記号を用いて図形を表示しています。記号●で初期化されると以下のようになります。

実行例
--  start!!  --

●●
●●●
●●●●
●●●●●
-- finish!!  --

Squareクラス

Square.java
public class Square extends DisplayFigure {

    private char symbol;

    public Square(char symbol) {
        this.symbol = symbol;
    }

    public void printFigure() {
        System.out.print(symbol);
    }
}

このクラスもCircle.java同様にDisplayFigure.javaを継承しています。このクラスを記号■で初期化すると以下の実行結果になります。このプログラムを動かすMainクラスは最後に説明します。

実行例
--  start!!  --

■■
■■■
■■■■
■■■■■
-- finish!!  --

CircleSquareは三角形が●か■で描画されているかが違うだけで、あとは共通の処理を行なっていることがわかります。

実際に動かしてみる

Mainクラスを作成して実際に動かしてみましょう。

Main.java
public class Main {

    public static void main(String[] args) {
        DisplayFigure circle = new Circle('●');
        DisplayFigure square =  new Square('■');
        circle.display();
        square.display();
    }
}
実行結果
--  start!!  --

●●
●●●
●●●●
●●●●●
-- finish!!  --
--  start!!  --

■■
■■■
■■■■
■■■■■
-- finish!!  --

ここで注目してほしいのは作成したインスタンスを抽象クラスの型の変数に代入している(アップキャスト)点です。そして、子クラスのメソッドを直接呼び出さずに抽象クラスである、DisplayFigureクラスのdisplay()を呼び出しています。このおかげで、ロジックを変更したい場合には、DisplayFigureクラスのdisplay()を変更するだけで済みます。

ロジックを変更してみる

最後にロジックを変更してみましょう。これまでは三角形を表示してきたので、四角形で表示するプログラムに書き換えてみます。

変更後のDisplayFigure.java
public abstract class DisplayFigure {

    public void init() {
        System.out.println("--  start!!  --");
    }

    public abstract void printFigure();

    public void finish() {
        System.out.println("-- finish!!  --");
    }

    /*  public final void display() {
        init();
        for(int i = 0; i < 5; i ++) {
            for(int j = 0; j <= i; j ++) {
                printFigure();
            }
            System.out.println();
        }
        finish();
    } */

    // 四角形を表示するプログラムに変更
    public final void display() {
        init();
        for (int i = 0; i < 5; i++) {
            for (int j = 0; j < 5; j++) {
                printFigure();
            }
            System.out.println();
        }
        finish();
    }
}

実行すると…

変更後の実行結果
--  start!!  --
●●●●●
●●●●●
●●●●●
●●●●●
●●●●●
-- finish!!  --
--  start!!  --
■■■■■
■■■■■
■■■■■
■■■■■
■■■■■
-- finish!!  --

DisplayFigureクラスのprint()を変更するだけでCircleSquareの2つのクラスの振る舞いを変更することができました。


参考書籍: 増補改訂版Java言語で学ぶデザインパターン入門

0
0
0

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
  3. You can use dark theme
What you can do with signing up
0
0