Template Method

template-method.png

概要

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

やり方

abstractクラスを作って、その中にpublic finalなメンバ関数を作る
その、public finalなメンバ関数の中に、abstractな関数を入れる。

スタート 似たような2つのクラスが出来てしまった

Coffee.java Tea.java
package template_method;
 
public class Coffee {
    public void prepareRecipe(){
        boilWater();
        brewCoffeeGrinds();
        pourInCup();
        addSugarAndMilk();
    }
    public void boilWater(){
        System.out.println("お湯を沸かします");
    }
    public void brewCoffeeGrinds(){
        System.out.println("フィルタでコーヒーをドリップします");
    }
    public void pourInCup(){
        System.out.println("カップに注ぎます");
    }
    public void addSugarAndMilk(){
        System.out.println("砂糖とミルクを追加します");
    }
}
package template_method;
 
public class Tea {
    public void prepareRecipe(){
        boilWater();
        steepTeaBag();
        pourInCup();
        addLemon();
    }
    public void boilWater(){
        System.out.println("お湯を沸かします");
    }
    public void steepTeaBag(){
        System.out.println("紅茶を浸します");
    }
    public void addLemon(){
        System.out.println("レモンを追加します");
    }
    public void pourInCup(){
        System.out.println("カップに注ぎます");
    }
}

これを改良するための抽象クラスを作る

package template_method;
 
public abstract class CaffeineBeverage {
    //サブクラスに上書きされたくないのでfinal修飾子を「つける
    public final void prepareRecipe(){
        boilWater();
        brew();
        pourInCup();
        addCondiments();
    }
    abstract void brew();
    abstract void addCondiments();
    void boilWater(){
        System.out.println("お湯を沸かします");
    }
    void pourInCup(){
        System.out.println("カップに注ぎます");
    }
 
}

CaffeineBeverageクラスのおかげでスッキリとしたCoffeeとTeaクラス
Coffee.java Tea.java
package template_method;
 
public class Coffee  extends CaffeineBeverage{
 
    public void brew(){
        System.out.println("フィルタでコーヒーをドリップします");
    }
    public void addCondiments(){
        System.out.println("砂糖とミルクを追加します");
    }
}
package template_method;
 
public class Tea extends CaffeineBeverage{
    public void brew(){
        System.out.println("紅茶を浸します");
    }
    public void addCondiments(){
        System.out.println("レモンを追加します");
    }
}

参考にした本


const-member-function hollywood-principle

サポートサイト Wikidot.com const-member-functionhollywood-principle