最近在學design pattern,看到一個模式很熟悉,原來是曾經在一個爬蟲系統中見過使用這個架構。
這個模式叫 樣板方法模式
通常應用在有一套固定步驟的系統中,
例如,我曾見過的爬蟲系統:
1.開始
2.爬文章
3.整理格式
4.寫入DB
5.結束
就可以把這樣的流程定義在AbstractClass的templateMethod中
結構圖長這樣:
現在以一個煮咖啡因飲料當作範例,
煮飲料的流程是:
首先宣告共同流程的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.
*
*/
}
https://refactoring.guru/design-patterns/template-method
https://www.oreilly.com/library/view/head-first-design/0596007124/