1. 程式人生 > 實用技巧 >大話設計模式:模板方法模式

大話設計模式:模板方法模式

什麼是模板方法?即讓工作或流程順序按照寫好的模板進行下去,同時還可以自定義流程,以及簡化流程。

舉例:沖泡茶和咖啡均分四步進行:

  1. 把水煮沸
  2. 沖泡咖啡(茶)
  3. 把咖啡(茶)倒入杯子
  4. 加糖(檸檬)

一般寫法

咖啡類

public class Coffee {

    public void prepare() {
        /**
         * 製作咖啡:
         * 1。 把水煮沸
         * 2。 用水沖泡
         * 3。 把咖啡倒進杯子
         * 4。 加糖
         */
        boilWater();
        brewCoffee();
        pourInCup();
        addSuger();
    }

    public void boilWater() {
        System.out.println("把水煮沸");
    }

    public void brewCoffee() {
        System.out.println("用水沖泡咖啡");
    }

    public void pourInCup() {
        System.out.println("把咖啡倒進杯子");
    }

    public void addSuger() {
        System.out.println("加糖");
    }

}

茶類

public class Tea {

    public void prepare() {
        /**
         * 製作茶:
         * 1。 把水煮沸
         * 2。 用水沖泡
         * 3。 把茶倒進杯子
         * 4。 加檸檬
         */
        boilWater();
        pourInCup();
        pourInCup();
        addLemon();
    }

    public void boilWater() {
        System.out.println("把水煮沸");
    }

    public void brewTea() {
        System.out.println("用水沖泡茶");
    }

    public void pourInCup() {
        System.out.println("把茶倒進杯子");
    }

    public void addLemon() {
        System.out.println("加檸檬");
    }

}

測試類

public class Test01 {

    /**
     * 這種實現方式有很多重複的程式碼
     */
    public static void main(String[] args) {
        Coffee coffee = new Coffee();
        Tea tea = new Tea();
        coffee.prepare();
        System.out.println("---------------");
        tea.prepare();
    }

}

模板方法

定義抽象的模板方法,把公共方法抽離出來,其它交給子類去實現

public abstract class DrinksTemplate {

    /**
     * 設定為final,不讓子類去覆蓋或篡改流程
     */
    final public void prepare() {
        boilWater();
        brew();
        pourInCup();
        add();
    }

    public void boilWater() {
        System.out.println("把水煮沸");
    }

    /**
     * 交給子類實現
     */
    public abstract void brew();

    public void pourInCup() {
        System.out.println("把飲料倒進杯子");
    }

    public abstract void add();

}

咖啡類

public class Coffee extends DrinksTemplate {

    @Override
    public void brew() {
        System.out.println("用沸水沖泡咖啡");
    }

    @Override
    public void add() {
        System.out.println("加糖");
    }
}

茶類

public class Tea extends DrinksTemplate {

    @Override
    public void brew() {
        System.out.println("用沸水沖泡茶");
    }

    @Override
    public void add() {
        System.out.println("加檸檬");
    }
}

測試類

public class Test01 {

    public static void main(String[] args) {
        Coffee coffee = new Coffee();
        Tea tea = new Tea();
        coffee.prepare();
        System.out.println("-----------");
        tea.prepare();
    }

}

使用鉤子函式

鉤子函式是在抽象模板方法中定義的,它的作用就是控制流程中的某個步驟是否執行、簡化流程,子類可以選擇覆蓋。比如,在準備給使用者沖泡咖啡或茶之前詢問使用者是否需要加糖或者檸檬,不需要就不進行加糖或檸檬這一步驟了。

抽象模板方法

public abstract class DrinksTemplate {

    /**
     * 設定為final,不讓子類去覆蓋或篡改流程
     */
    final public void prepare() {
        boilWater();
        brew();
        pourInCup();
        if (ifAdd()) {
            add();
        }
    }

    public void boilWater() {
        System.out.println("把水煮沸");
    }

    /**
     * 交給子類實現
     */
    public abstract void brew();

    public void pourInCup() {
        System.out.println("把飲料倒進杯子");
    }

    public abstract void add();

    /**
     * 鉤子函式
     */
    public Boolean ifAdd() {
        return true;
    }

}

只讓茶類去覆蓋鉤子函式

@Data
public class Tea extends DrinksTemplate {

    private Boolean ifAdd;

    @Override
    public void brew() {
        System.out.println("用沸水沖泡茶");
    }

    @Override
    public void add() {
        System.out.println("加檸檬");
    }

    @Override
    public Boolean ifAdd() {
        return ifAdd;
    }
}

測試類

@SuppressWarnings("Duplicates")
public class Test01 {

    public static void main(String[] args) {
        Coffee coffee = new Coffee();
        Tea tea = new Tea();
        // 啟用鉤子函式
        tea.setIfAdd(false);
        coffee.prepare();
        System.out.println("==========");
        tea.prepare();
    }

}

測試結果

把水煮沸
用沸水沖泡咖啡
把飲料倒進杯子
加糖
==========
把水煮沸
用沸水沖泡茶
把飲料倒進杯子