headfirst设计模式第八章读书笔记--模板方法模式

思想

模板方法模式很容易理解。思想基本如下:先在父类规定了具体的算法步骤以及算法顺序。父类可以给出部分步骤的具体实现,也可以都只给出方法框架,没有具体实现。在子类具体实现各个步骤的方法,但是各个步骤间的顺序在父类已经确定,子类无法通常不应该更改。如果规定算法顺序的方法在父类被定义成final,则子类就无法更改了。具体实现,根据实际需求确定。

。其目的一方面是减少代码重复,达到代码复用的目的
。另一方面也可以在父类控制和限制子类的动作。
。父类(泛化类)规定了一个算法框架,大多数时候,只要修改子类即可。
。将具体算法和实现相分离,各司其职(单一职责),基类负责算法设计,(某些情况也会涉及一点实际实现),子类专司具体算法实现。

咖啡因饮料代码实现

headfirst设计模式第八章读书笔记--模板方法模式_第1张图片

 

 

CaffeineBeverageWithHook.Java

package judge;

public abstract  class CaffeineBeverageWithHook {
    public void prepareRecipe(){      //此处若定义为final类可防止子类改变它的顺序
        boilWater();
        brew();
        pourInCup();
        if(customerWantsCondiments()){
            addCondiments();
        }
    }
    
    abstract void brew();
    
    abstract void addCondiments();
    
    void boilWater() {
        System.out.println("Boiling water");
    }
    
    void pourInCup() {
        System.out.println("Pouring into cup");
    }
    
    boolean customerWantsCondiments(){     //钩子方法,子类决定是否覆盖他
        return true;
    }
}

 

CoffeeWithHook.Java

package judge;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import javax.swing.plaf.basic.BasicInternalFrameTitlePane.IconifyAction;

public class CoffeeWithHook extends CaffeineBeverageWithHook{
    @Override
    void brew() {
        // TODO Auto-generated method stub
      System.out.println("Dripping Coffee");    
    }
     
     @Override
    void addCondiments() {
        // TODO Auto-generated method stub
      System.out.println("Adding Sugar");    
    }
     
     @Override
    boolean customerWantsCondiments() {            //覆盖钩子
        // TODO Auto-generated method stub
        String answer = getUserInput();
        if(answer.toLowerCase().startsWith("y")){
            return true;
        }
        else {
            return false;
        }
    }
     
     private String getUserInput (){
         String answer = null;
         
         System.out.println("would you like milk? (y/n)");
         
         BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
         try {
            answer = in.readLine();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
         if (answer == null) {
            return "no";
        }
         return answer;
     }
     
}

 

Test.Java

package testJudge;

import judge.CoffeeWithHook;

public class Test {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        CoffeeWithHook coffeeWithHook = new CoffeeWithHook();
        coffeeWithHook.prepareRecipe();
    }

}

 

总结

我们有两个重要的部分,一个是抽象基类,一个是具体子类。
在抽象基类中我们要提供基本方法,抽象方法,钩子函数(可选)以及模板方法(final)。
在具体子类中我们要实现基类中的抽象方法,可选的钩子方法
模板方法就是准备一个抽象类,将部分逻辑以具体方法的形式实现,然后声明一些抽象方法交由子类实现剩余逻辑,用钩子方法给予子类更大的灵活性,最后将方法汇总构成一个不可改变的模板方法。

 

适用场景
1.算法或操作遵循相似的逻辑
2.重要、复杂的算法,核心算法设计为模板算法

 


优点和缺点
优点

1.封装性好
2.复用性高
3.屏蔽细节
4.便于维护
缺点:继承的唯一性

你可能感兴趣的:(headfirst设计模式第八章读书笔记--模板方法模式)