『Head Firstデザインモード』ノートを読む.第八章


1.テンプレート方法(Template Method)モード部分
----設計パズルの解答----
public abstract class Drink {
    public abstract void prepareRecipe();
    
    public void boilWater() {
        System.out.println("Boiling water");
    }
   
    public void pourInCpu() {
        System.out.println("Pouring into cup");
    }
}

注意:CoffeeクラスとTeaクラスを変更し、Drinkを継承します.
------------
*テンプレートメソッドは、アルゴリズムのステップを定義し、サブクラスが1つ以上のステップを実装できるようにします.
*テンプレートメソッドにより、アルゴリズムは1つの場所にのみ存在し、修正が容易になります.
テンプレートメソッドモード:アルゴリズムのスケルトンを1つのメソッドで定義し、いくつかのステップをサブクラスに遅延します.テンプレートメソッドは、サブクラスがアルゴリズム構造を変更することなく、アルゴリズムのいくつかのステップを再定義することができる.
*テンプレートメソッド定義のアルゴリズムステップが変更されないことを保証するために、テンプレートメソッドはfinalとして宣言される.
*フック(hook)はコールバック関数であり、テンプレートメソッドクラスのアルゴリズムに影響を与える条件として使用できます.
ソフトウェア設計の原則:私たちを呼び出さないでください.私たちはあなたを呼び出します.この原則はハリウッドの原則となっている.
*ハリウッドの原則は、類間の過度な依存をできるだけ減らし、「腐敗・敗北依存」を防ぐことができる.
参照
----Brain Power解答----
ハリウッドの原則として使われるモデルは、ストラテジーモード、コマンドモード、アダプターモード、デコレーションモード、外観(Facade)モードです
------------
参照
----続けて解答を見ます----
テンプレートメソッド(Template Method)モード->サブクラスがアルゴリズムを実装する方法を決定する手順
ポリシー(Strategy)モード->互換性のある動作をカプセル化し、依頼を使用してどの動作を採用するかを決定します.
ファクトリメソッド(Factory Method)モード->どのクラスをインスタンス化するかをサブクラスで決定
------------
*ポリシー(Strategy)モードとテンプレートメソッド(Template Method)モードの違い:ポリシーモードは完全なアルゴリズムを実現し、各アルゴリズムの間で互いに置き換えることができる.テンプレートメソッドはアルゴリズムのスケルトンのみを定義し、一部のステップはサブクラスで実装する必要があります.
2.テンプレートメソッド(Template Method)モードのまとめ
*「テンプレートメソッド」では、アルゴリズムのステップを定義し、これらのステップの実装をサブクラスに遅延します.
*テンプレートメソッドモードは、コード多重化の重要なテクニックを提供します.
*テンプレートメソッドの抽象クラスは、特定のメソッド、抽象メソッド、フックを定義できます.
*抽象メソッドはサブクラスによって実装されます.
*フックは、抽象クラスで仕事をしないか、デフォルトのことしかしない方法で、サブクラスは上書きするかどうかを選択できます.
*サブクラスがテンプレートメソッドのアルゴリズムを変更しないように、テンプレートメソッドをfinalとして宣言できます.
*ハリウッドの原則は、下位モジュールをどのように呼び出すか、いつ呼び出すかを決定するために、意思決定権を上位モジュールに置くことを示しています.
*実際の世界では、多くのテンプレートメソッドパターンの変形が見られます.すべてが一目で認識されることを期待しないでください.
*ポリシー(Strategy)モードとテンプレートメソッド(Template Method)モードは、アルゴリズムをカプセル化し、前者は組合せ、後者は継承を使用します.
*ファクトリメソッド(Factory Method)は、テンプレートメソッド(Template Method)の特別なバージョンです.
3.テンプレートメソッド(Template Method)モードの例
//   
public abstract class Guide {
   
    public final void leadTour() {
        this.buyTickets();
        if (needRest()) {//   
            this.bookingHotel();
        }
        this.conveneVisitors();
        this.goToScenicSpot();
        this.visit();
        if (needRest()) {//   
            this.sleep();
        }
        this.getBack();
    }

    //      
    public abstract void buyTickets();

    //     
    public abstract void bookingHotel();

    //     
    public void conveneVisitors() {
        System.out.println("Convening visitors.");
    }

    //     
    public void goToScenicSpot() {
        System.out.println("Go to the scenic spot.");
    }

    //   
    public void visit() {
        System.out.println("Visit the scenic spot.");
    }

    //   
    public void sleep() {
        System.out.println("Have a rest.");
    }

    //   
    public abstract void getBack();

    //       
    public boolean needRest() {
        return true;
    }
}

//        
public class BeiJingGuide extends Guide {
    @Override
    public void buyTickets() {
        System.out.println("Buy bus tickets.");
    }

    @Override
    public void bookingHotel() {
        //        ,         
    }

    @Override
    public void getBack() {
        System.out.println("Get back by bus.");
    }

    //     ,    
    @Override
    public boolean needRest() {
        return false;
    }
}

//        
public class HaiNanGuide extends Guide {
    @Override
    public void buyTickets() {
        System.out.println("Buy plane tickets.");
    }

    @Override
    public void bookingHotel() {
        System.out.println("Booking HaiNan Hotel.");
    }

    @Override
    public void getBack() {
        System.out.println("Get back by air.");
    }
}

--END--