とある超人のデザインパターン〜Template Methodで部分的に異なる振る舞いを〜

はじめに

今回はGoFデザインパターンの一つであるTemplate Methodパターンについて書きました。自分が覚えるためのまとめ記事なので説明が甘いところは多々あると思います。ご意見、補足等ありましたらぜひどうぞ。

(V)o\o(V):フォフォ・・。
(o|o):どうしたんだ、元気ないな?
(V)o\o(V):フォッフォ・・。
(o|o):ん?分身の行動パターンが単調で困っている?
(V)o\o(V):フォフォ。
(o|o):分身って全部同じクラスから作ってるんだっけ?
(V)o\o(V):フォ。
(o|o):そうだなー、じゃあ新しいクラスを作ったらどう?
(V)o\o(V):フォ?

機能を追加

(o|o):例えば、今のクラスがこれだとする。

public class Baru {

    public action() {
        move();
        attack();
        defense();
    }

    private move() {
        ・・・
    }

    private attack() {
        ・・・
    }

    private defense() {
        ・・・
    }

}

(o|o):メソッドの抽出はよくできているが、これじゃあ動きが単調になるのも仕方ない。
(V)o\o(V):フォ。
(o|o):そこで、別々の攻撃手段を持ったクラスを作成してみる。

// 火炎で攻撃するクラス
public class FireBaru {

    public action() {
        move();
        attack();
        defense();
    }

    private move() {
        ・・・
    }

    private attack() {
        fire();
    }

    private defense() {
        ・・・
    }

}

// 稲妻で攻撃するクラス
public class ThunderBaru {

    public action() {
        move();
        attack();
        defense();
    }

    private move() {
        ・・・
    }

    private attack() {
        thunder();
    }

    private defense() {
        ・・・
    }

}

(o|o):これで君の仕様は満たされたわけだが、コードがかなり重複しているね。
(V)o\o(V):フォ。
(o|o):そこで、Template Methodパターンを適用してみよう。

Template Methodパターンを適用

(o|o):まず、共通部分を抽象クラスにまとめる。
(V)o\o(V):フォ。
(o|o):で、変化をつけたい動作は実装クラスでオーバーライドさせるってわけ。

// 抽象クラス
public abstract class Baru {

    // テンプレートメソッド
    public void action() {
        move();
        attack();
        defense();
    }

    // 共通の動作
    private void move() {
        ・・・
        System.exit(0);
    }

    // 変化を付けたい動作
    protected abstract void attack();

    // 共通の動作
    private void defense() {
        ・・・
    }

}

// 火炎で攻撃するクラス
public class FireBaru extends Baru {

    @Override
    protected void attack() {
        fire();
    }

}

// 稲妻で攻撃するクラス
public class ThunderBaru extends Baru {

    @Override
    protected void attack() {
        thunder();
    }

}

(o|o):これでどうだい。
(V)o\o(V):フォッフォー!
(o|o):これでお前を倒せるぞ?なるほどね。がんばって!
(V)o\o(V):フォ!
(o|o):どういたしまして。

後日談

(V)o\o(V):フォ・・(分身が動いたらオレまで消える)
(o|o):(クスッ)

本日のクレーム

監督:クラス、増えすぎ!

参考

サルでもわかる 逆引きデザインパターン 第3章 逆引きカタログ J2EE編 Template Method(テンプレートメソッド)


Template Methodパターン


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

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


パターン指向リファクタリング入門~ソフトウエア設計を改善する27の作法

パターン指向リファクタリング入門~ソフトウエア設計を改善する27の作法


リファクタリング―プログラムの体質改善テクニック (Object Technology Series)

リファクタリング―プログラムの体質改善テクニック (Object Technology Series)

  • 作者: マーチンファウラー,Martin Fowler,児玉公信,平澤章,友野晶夫,梅沢真史
  • 出版社/メーカー: ピアソンエデュケーション
  • 発売日: 2000/05
  • メディア: 単行本
  • 購入: 94人 クリック: 3,091回
  • この商品を含むブログ (312件) を見る