iT邦幫忙

0

Design Pattern - Template method(樣板方法模式),來開一間飲料店吧

  • 分享至 

  • xImage
  •  

樣板方法模式-Template method

最近在學design pattern,看到一個模式很熟悉,原來是曾經在一個爬蟲系統中見過使用這個架構。


應用

這個模式叫 樣板方法模式
通常應用在有一套固定步驟的系統中,
例如,我曾見過的爬蟲系統:

1.開始
2.爬文章
3.整理格式
4.寫入DB
5.結束

就可以把這樣的流程定義在AbstractClass的templateMethod中

結構圖長這樣:
template method


範例

現在以一個煮咖啡因飲料當作範例,
煮飲料的流程是:

  1. 把水煮滾
  2. 煮原料(咖啡包、茶包)
  3. 把飲料倒入杯中
  4. 如果需要,可以加料

首先宣告共同流程的abstract class

public abstract class CaffeineBeverage {

    // templateMethod:定義煮飲料的流程,並宣告為final,避免被subClass override
    final void prepareDrink() {  
        boilWater();
        brew();
        pourInCup();
        if (customerWantsCondiments()) {
            addCondiments();
        }
    }

    // 因應不同飲料有不同的煮法,宣告為abstract,subclass必須override
    abstract void brew();  
    abstract void addCondiments();

    // 所有飲料共通的流程,所以在abstract class這邊就寫邏輯了,但如有需要還是可以被subclass override
    void boilWater() {
        System.out.println("Boiling water.");
    }

    void pourInCup() {
        System.out.println("Pouring into water.");
    }

    // Hook,通常會是空的,可以由subClass決定要不要override
    boolean customerWantsCondiments() { 
        return true;
    }

}

接下來是concreteClass,先是Coffee類別

public class Coffee extends CaffeineBeverage {
    @Override
    void brew() {
        System.out.println("Brew coffee.");
    }

    @Override
    void addCondiments() {
        System.out.println("Add milk.");
    }
}

接下來是另一個concreateClass,NoSugarTea類別

public class NoSugarTea extends CaffeineBeverage {
    @Override
    void brew() {
        System.out.println("Brew no sugar tea.");
    }

    @Override
    void addCondiments() {
        System.out.println("Don't add condiments. This shouldn't be printed.");
    }

    // 這邊有override hook,因為無糖茶不想加料,所以return false
    @Override
    boolean customerWantsCondiments() { 
        return false;
    }
}

最後是client code

public class CaffeineBeverageClient {
    public static void main(String[] args) {

        System.out.println("I would like a cup of coffee.");
        CaffeineBeverage coffee = new Coffee();
        coffee.prepareDrink();

        System.out.println("");
        System.out.println("I would like a cup of no sugar tea.");
        CaffeineBeverage noSugarTea = new NoSugarTea();
        noSugarTea.prepareDrink();

    }
    
    /**
     * output:
     * 
     * I would like a cup of coffee.
     * Boiling water.
     * Brew coffee.
     * Pouring into water.
     * Add milk.
     *
     * I would like a cup of no sugar tea.
     * Boiling water.
     * Brew no sugar tea.
     * Pouring into water.
     * 
     */
}


Reference:

https://refactoring.guru/design-patterns/template-method
https://www.oreilly.com/library/view/head-first-design/0596007124/


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言