一:模板模式定義(AQS的設計):
定義一個操作中的算法的框架,而將一些步驟延遲到子類中。使得子類在不改變一個算法的結構即可以重新定義該算法的某些特定步驟。
二:模板模式特點:
模板模式主要由抽象的模板類,具體的模板類以及測試類三部分組成。其中在抽象的模板類中可以定義基本方法(第一部分是由protected修飾的方法讓子類繼承,實現自己的邏輯,從而將一部分方法的實現延遲到子類上;第二部分是由抽象類已經實現的具體方法,該方法的實現和具體的子類無關),模板方法(該方法由final修飾,子類不可以直接更改重寫,其目的就是爲了保證該類的算法基本框架,子類可以做具體的實現,但是不可以改變執行順序或者增加減少執行數量),鉤子方法(protected類型,作用於模板方法,因爲子類不可以直接修改模板方法,所以在模板方法中加邏輯控制,這樣子類重寫鉤子方法就相當於間接改變了模板方法)。
三:模板模式實現:
抽象的模板類:
public abstract class DoFishTemplate {
// 基本方法:1:由子類繼承具體實現的抽象方法;2:父類實現的具體方法。
// 做菜的第一步:備菜
protected abstract void preparation();
// 做菜的第二步:炒菜
protected abstract void cooking();
// 做菜的第三部:上菜
protected abstract void server();
// 做菜的第四部:洗鍋。由父類具體實現。不管做什麼菜這個步驟是固定不可改變的
protected void wash() {
System.out.println("父類已經實現:洗鍋");
}
// 模板方法,將基本方法進行組裝,從而形成做菜的算法框架。
public final void dofish() {
if (isPreparation()) {
this.preparation();
}
this.cooking();
this.server();
this.wash();
}
// 鉤子方法。返回值確定模板方法是否調用基本方法
// 默認是備菜的。當做涼菜的時候不需要備菜,做熱菜需要備菜。
public boolean isPreparation() {
return true;
}
}
具體的實現類:
public class ColdFish extends DoFishTemplate {
private boolean isPreparation;
@Override
protected void preparation() {
System.out.println("涼菜的準備階段");
}
@Override
protected void cooking() {
System.out.println("涼菜的製作階段");
}
@Override
protected void server() {
System.out.println("涼菜的上菜階段");
}
// 子類重新鉤子方法。決定是否需要備菜
public boolean isPreparation() {
return isPreparation;
}
public void setPreparation(boolean isPreparation) {
this.isPreparation = isPreparation;
}
}
測試類:
public class DoFishTest {
public static void main(String[] args) {
// 向上轉型(非靜態編譯看左,運行看右。靜態的都看左)
DoFishTemplate coldFish = new ColdFish();
// 若子類重寫了父類的方法則調用的是子類自己的邏輯,若沒有重寫則調用父類的邏輯
// 編譯錯誤,因爲父類無此方法。
// coldFish.setPreparation(false);
//向上轉型後再向下轉型
((ColdFish) coldFish).setPreparation(false);
coldFish.dofish();
}
}