Template Methodパターン

Head First デザインパターンのメモ。

Template Methodパターン

メソッドにおけるアルゴリズムの骨組みを定義し、いくつかの手順をサブクラスに先送りします。
Template Methodは、アルゴリズムの構造を変えることなく、
アルゴリズムのある手順をサブクラスに再定義させます。

フック

抽象クラスで定義され、空の実装やデフォルトの実装をだけを提供するメソッド。
必要に応じてアルゴリズムをフックする機能をサブクラスに提供する

実装

// 飲み物作成のスーパークラス
public class CaffeineBeverage {
    // Coffee、Teaはどちらもこのメソッドを使って作ることになる
    // アルゴリズムを変更しないようにfinalとして宣言
    final void prepareRecipe() {
        boilWater();
        brew();
        pourInCup();
        if (customerWantsCondiments()) {
            // トッピングが欲しい場合のみ
            addCondiments();
        }
    }
    abstract void brew();
    abstract void addCondiments();

    void boilWater() {
        System.out.println("お湯をわかします");
    }
    void pourInCup() {
        System.out.println("カップに注ぎます");
    }
   // フック。オーバーライドしなくてもよい
    boolean customerWantsCondiments() {
        return true;
    }
}

public class Tea extends CaffeineBeverage {
    public void brew() {
        System.out.println("紅茶を浸します");
    }
    public void addCondiments() {
        System.out.println("レモンを追加します");
    }
}

public class Coffee extends CaffeineBeverage {
    public void brew() {
        System.out.println("コーヒーをドリップします");
    }
    public void addCondiments() {
        System.out.println("砂糖とミルクを追加します");
    }
    // フックのオーバーライド
    public boolean customerWantsCondiments() {
        // 何らかの処理
    }
}

ハリウッド原則

こちらを呼び出さないでください。こちらから呼び出します。
(Don't call us, we'll call you.)

低水準コンポーネントがいつどのように必要になるかについては
高水準コンポーネントが判断する。依存性の腐敗を回避する方法。