更新時(shí)間:2021-08-24 來(lái)源:黑馬程序員 瀏覽量:
在面向?qū)ο蟪绦蛟O(shè)計(jì)過(guò)程中,程序員常常會(huì)遇到這種情況:設(shè)計(jì)一個(gè)系統(tǒng)時(shí)知道了算法所需的關(guān)鍵步驟,而且確定了這些步驟的執(zhí)行順序,但某些步驟的具體實(shí)現(xiàn)還未知,或者說(shuō)某些步驟的實(shí)現(xiàn)與具體的環(huán)境相關(guān)。
例如,去銀行辦理業(yè)務(wù)一般要經(jīng)過(guò)以下4個(gè)流程:取號(hào)、排隊(duì)、辦理具體業(yè)務(wù)、對(duì)銀行工作人員進(jìn)行評(píng)分等,其中取號(hào)、排隊(duì)和對(duì)銀行工作人員進(jìn)行評(píng)分的業(yè)務(wù)對(duì)每個(gè)客戶(hù)是一樣的,可以在父類(lèi)中實(shí)現(xiàn),但是辦理具體業(yè)務(wù)卻因人而異,它可能是存款、取款或者轉(zhuǎn)賬等,可以延遲到子類(lèi)中實(shí)現(xiàn)。
模板方法(Template Method)模式包含以下主要角色:
抽象類(lèi)(Abstract Class):負(fù)責(zé)給出一個(gè)算法的輪廓和骨架。它由一個(gè)模板方法和若干個(gè)基本方法構(gòu)成。
模板方法:定義了算法的骨架,按某種順序調(diào)用其包含的基本方法。
基本方法:是實(shí)現(xiàn)算法各個(gè)步驟的方法,是模板方法的組成部分。基本方法又可以分為三種:
抽象方法(Abstract Method) :一個(gè)抽象方法由抽象類(lèi)聲明、由其具體子類(lèi)實(shí)現(xiàn)。
具體方法(Concrete Method) :一個(gè)具體方法由一個(gè)抽象類(lèi)或具體類(lèi)聲明并實(shí)現(xiàn),其子類(lèi)可以進(jìn)行覆蓋也可以直接繼承。
鉤子方法(Hook Method) :在抽象類(lèi)中已經(jīng)實(shí)現(xiàn),包括用于判斷的邏輯方法和需要子類(lèi)重寫(xiě)的空方法兩種。
一般鉤子方法是用于判斷的邏輯方法,這類(lèi)方法名一般為isXxx,返回值類(lèi)型為boolean類(lèi)型。
具體子類(lèi)(Concrete Class):實(shí)現(xiàn)抽象類(lèi)中所定義的抽象方法和鉤子方法,它們是一個(gè)頂級(jí)邏輯的組成步驟。
【例】炒菜
炒菜的步驟是固定的,分為倒油、熱油、倒蔬菜、倒調(diào)料品、翻炒等步驟?,F(xiàn)通過(guò)模板方法模式來(lái)用代碼模擬。類(lèi)圖如下:
代碼如下:
public abstract class AbstractClass { public final void cookProcess() { //第一步:倒油 this.pourOil(); //第二步:熱油 this.heatOil(); //第三步:倒蔬菜 this.pourVegetable(); //第四步:倒調(diào)味料 this.pourSauce(); //第五步:翻炒 this.fry(); } public void pourOil() { System.out.println("倒油"); } //第二步:熱油是一樣的,所以直接實(shí)現(xiàn) public void heatOil() { System.out.println("熱油"); } //第三步:倒蔬菜是不一樣的(一個(gè)下包菜,一個(gè)是下菜心) public abstract void pourVegetable(); //第四步:倒調(diào)味料是不一樣 public abstract void pourSauce(); //第五步:翻炒是一樣的,所以直接實(shí)現(xiàn) public void fry(){ System.out.println("炒啊炒啊炒到熟啊"); } } public class ConcreteClass_BaoCai extends AbstractClass { @Override public void pourVegetable() { System.out.println("下鍋的蔬菜是包菜"); } @Override public void pourSauce() { System.out.println("下鍋的醬料是辣椒"); } } public class ConcreteClass_CaiXin extends AbstractClass { @Override public void pourVegetable() { System.out.println("下鍋的蔬菜是菜心"); } @Override public void pourSauce() { System.out.println("下鍋的醬料是蒜蓉"); } } public class Client { public static void main(String[] args) { //炒手撕包菜 ConcreteClass_BaoCai baoCai = new ConcreteClass_BaoCai(); baoCai.cookProcess(); //炒蒜蓉菜心 ConcreteClass_CaiXin caiXin = new ConcreteClass_CaiXin(); caiXin.cookProcess(); } }
注意:為防止惡意操作,一般模板方法都加上 final 關(guān)鍵詞。
JavaScript面向?qū)ο笮薷臉?biāo)簽頁(yè)詳解