1.概念
1.1.是什么砚哗?
在模板模式(Template Pattern)中龙助,一個抽象類公開定義了執(zhí)行它的方法的方式/模板。它的實(shí)現(xiàn)類按需要重寫方法實(shí)現(xiàn)蛛芥,但調(diào)用的控制邏輯由抽象類控制提鸟。
1.2.設(shè)計(jì)結(jié)構(gòu)
①. 模板模式主要由抽象模板(Abstract Template)角色和具體模板(Concrete Template)角色組成。
- 抽象模板:定義一些抽象操作仅淑,并且規(guī)定這些抽象操作的執(zhí)行邏輯称勋。
- 具體模板:重定義這些抽象操作以提供具體的行為,不能修改整個模板的執(zhí)行邏輯涯竟,可以實(shí)現(xiàn)豐富的方法操作赡鲜。
②. 模板方法是一種代碼復(fù)用的基本技術(shù)。它們在類庫中尤為重要庐船,它們提取了類庫中的公共行為银酬。模板方法導(dǎo)致一種反向的控制結(jié)構(gòu),這種結(jié)構(gòu)有時被稱為“好萊塢法則”筐钟,即“別找我們揩瞪,我們找你”。這指的是一個父類調(diào)用一個子類的操作篓冲。
- 在模版方法中定義了整個模板的骨架李破,同時還有公有的具體的操作宠哄,另外還應(yīng)該具備必須實(shí)現(xiàn)的抽象操作和可實(shí)現(xiàn)的抽象操作(鉤子操作)
- 鉤子操作,即一些非必需的省缺操作喷屋,通過子類實(shí)現(xiàn)是否需要該操作琳拨,對抽象類的控制邏輯產(chǎn)生影響瞭恰。該鉤子在抽象類中定義屯曹,因此父類默認(rèn)控制邏輯中可以不需要該操作。簡單來說惊畏,抽象類通過if判斷是否執(zhí)行某一個方法恶耽,而該判斷權(quán)交給子類根據(jù)場景來個性化實(shí)現(xiàn)。
2.應(yīng)用
- 當(dāng)多個相似事物在操作上步驟多數(shù)相同的情況下颜启,將相同操作提為公有模塊偷俭,而不同部分提為抽象操作,而使用重寫來實(shí)現(xiàn)各自的邏輯缰盏。
3.案例
3.1.標(biāo)準(zhǔn)的模板設(shè)計(jì)模式
①. Abstract Template
public abstract class TemplateDesignPatterns2 {
/**
* 模板方法執(zhí)行邏輯涌萤,要用final關(guān)鍵字進(jìn)行修飾,只可重寫不可修改
*/
public final void coreLogicMethod() {
System.out.println("執(zhí)行邏輯:");
commonStart();
uniqueStep();
if (isHasCommonEnd()) {
commonEnd();
}
}
/**
* 公共方法口猜,邏輯一定執(zhí)行
*/
private void commonStart() {
System.out.println("1.調(diào)用commonStart...");
}
/**
* 子類必須重新實(shí)現(xiàn)方法负溪,邏輯一定執(zhí)行
*/
protected abstract void uniqueStep();
/**
* 子類非必須重新實(shí)現(xiàn)方法,由子類根據(jù)場景重寫鉤子方法實(shí)現(xiàn)
*/
protected void commonEnd() {
System.out.println("3.調(diào)用commonEnd...");
}
/**
* 鉤子方法济炎,控制commonEnd是否需要執(zhí)行,默認(rèn)執(zhí)行
*/
protected boolean isHasCommonEnd() {
return true;
}
}
②. Concrete Template
public class TemplateDesignPatterns2Impl extends TemplateDesignPatterns2{
@Override
protected void uniqueStep() {
System.out.println("2.調(diào)用子類重寫uniqueStep...");
}
@Override
protected boolean isHasCommonEnd() {
return false;
}
public static void main(String[] args) {
TemplateDesignPatterns2 designPatterns2 = new TemplateDesignPatterns2Impl();
designPatterns2.coreLogicMethod();
}
}
- 若子類根據(jù)業(yè)務(wù)場景川抡,commonEnd()方法需要實(shí)現(xiàn),則直接重寫該方法须尚,若該方法不需要崖堤,如上圖控制鉤子去掉。
3.2.對上述代碼變相(類似thread中的調(diào)用方式)
public abstract class TemplateDesignPatterns {
/**
* 模板方法耐床, 要用final關(guān)鍵字進(jìn)行修飾密幔,只可重寫不可修改
*
* @return
*/
public TemplateDesignPatterns start() {
System.out.println("執(zhí)行邏輯:");
commonStep();
uniqueStep();
return null;
}
private void commonStep() {
System.out.println("1.公用方法...調(diào)用commonStep");
}
protected abstract void uniqueStep();
public static void main(String[] args) {
//隱式實(shí)現(xiàn)該方法
TemplateDesignPatterns designPattern = new TemplateDesignPatterns() {
@Override
protected void uniqueStep() {
System.out.println("2.個性實(shí)現(xiàn)私有邏輯...調(diào)用uniqueStep");
}
};
designPattern.start();
}
}
- 由于筆者閱讀書中介紹:Thread的run和 start為一個典型的模板設(shè)計(jì)模式,但由于JNI調(diào)用具體過程無法得知撩轰,故此寫了一個認(rèn)為的類似實(shí)現(xiàn)胯甩,若有錯誤請多多賜教。