設(shè)計模式之模板方法模式

定義

在一個方法中定義一個算法的骨架芭商,而將一些步驟延遲到子類中派草。模板方法使得子類可以在不改變算法結(jié)構(gòu)的情況下,重新定義算法中的某些步驟铛楣。

生活事例引入

咖啡沖泡法

  • 把水煮沸
  • 用沸水沖泡咖啡
  • 把咖啡倒進杯子
  • 加糖和牛奶
    茶沖泡法
  • 把水煮沸
  • 用沸水浸泡茶葉
  • 把茶倒進杯子
  • 加檸檬

可以發(fā)現(xiàn)上面兩種飲料的沖泡法在步驟上存在一樣的地方近迁,只是具體的動作不一樣,例如第四步都是沖泡的時候加一些佐料簸州,咖啡沖泡法是加的糖和牛奶鉴竭,茶沖泡法加的是檸檬

既然存在一些重復(fù)或者相似的地方,我們此時考慮將他們共同的部分抽取出來岸浑,放進一個基類中搏存。


下面進行代碼封裝
首先是抽取出來的抽象類

package templatepattern;

public abstract class CaffeineBeverage {
    final void prepareRecipe() {
        boidWater();
        brew();
        pourInCup();
        addCondiments();

    }
    abstract void brew();
    abstract void addCondiments();
    void boidWater() {
        System.out.println("Boiling Water");
    }
    void pourInCup() {
        System.out.println("Pouring into Cup");
    }
}

然后是Tea類

package templatepattern;

public class Tea extends CaffeineBeverage {
    @Override
    void brew() {
        System.out.println("Steeping the tea");
    }

    @Override
    void addCondiments() {
        System.out.println("Adding Lemon");

    }
}

然后是Coffee類

package templatepattern;

public class Coffee extends CaffeineBeverage {
    @Override
    void brew() {
        System.out.println("Dripping Coffee through filter");
    }

    @Override
    void addCondiments() {

        System.out.println("Adding Sugar and Milk");
    }
}

代碼解釋

  • 上述代碼中,抽象類中的prepareRecipe()方法是final類型的助琐,之所以這么做是因為這個方法定義了一系列的步驟祭埂,而又不想這些步驟被子類所刪減,因此讓這個方法類型是final兵钮。
  • 不管是coffee還是tea蛆橡,boidWater()和 pourInCup()方法的內(nèi)容都是一樣的,因此在父類中實現(xiàn)掘譬,但是具體添加的佐料不一樣泰演,泡的東西不一樣,因此這兩個方法在子類中具體實現(xiàn)葱轩。

模板方法定義了一個算法的步驟睦焕,并允許子類為一個或者多個步驟提供實現(xiàn)

進一步模板模式

使用鉤子

  • 鉤子就是一個空的方法,該方法什么也不做靴拱,這個方法在父類中垃喊,子類視情況決定要不要覆蓋他們。

用途舉例

package templatepattern;

public abstract class CaffeineBeverage {
    final void prepareRecipe() {
        boidWater();
        brew();
        pourInCup();
        addCondiments();
        hook();

    }
    abstract void brew();
    abstract void addCondiments();
    void boidWater() {
        System.out.println("Boiling Water");
    }
    void pourInCup() {
        System.out.println("Pouring into Cup");
    }
    void hook() {//hook就是一個鉤子袜炕,該方法什么也不做
        
    }
}
  • 鉤子實例
package templatepattern;

public abstract class CaffeineBeverage {
    final void prepareRecipe() {
        boidWater();
        brew();
        pourInCup();
        if (customerWantsCondiments()) {//此處加了條件語句
            addCondiments();
        }


    }
    abstract void brew();
    abstract void addCondiments();
    void boidWater() {
        System.out.println("Boiling Water");
    }
    void pourInCup() {
        System.out.println("Pouring into Cup");
    }
    boolean customerWantsCondiments() {//該方法就是一個鉤子本谜,子類可以覆蓋這個方法,但也不一定非得覆蓋
        return true;
    }

}

創(chuàng)建一個模板方法什么時候用鉤子偎窘,什么時候用抽象方法呢
當子類必須提供算法中某個方法或者步驟的實現(xiàn)時乌助,就使用抽象方法溜在,如果算法的這個部分是可選的,就用鉤子他托。如果選擇用鉤子的話掖肋,子類可以選擇實現(xiàn)這個鉤子,但并不強制這么做赏参。

好萊塢原則

別調(diào)用我們志笼,我們會調(diào)用你。

  • 比如在模板設(shè)計模式中,我們告訴子類,不要到用我們河劝,我們會調(diào)用你。

Applet Swing 還有Comparable接口的compareTo()方法都采用了模板方法模式

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末皇耗,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子揍很,更是在濱河造成了極大的恐慌郎楼,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件窒悔,死亡現(xiàn)場離奇詭異呜袁,居然都是意外死亡,警方通過查閱死者的電腦和手機简珠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進店門阶界,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人聋庵,你說我怎么就攤上這事膘融。” “怎么了祭玉?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵氧映,是天一觀的道長。 經(jīng)常有香客問我脱货,道長岛都,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任振峻,我火速辦了婚禮臼疫,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘扣孟。我一直安慰自己烫堤,他們只是感情好,可當我...
    茶點故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著塔逃,像睡著了一般。 火紅的嫁衣襯著肌膚如雪料仗。 梳的紋絲不亂的頭發(fā)上湾盗,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天,我揣著相機與錄音立轧,去河邊找鬼格粪。 笑死,一個胖子當著我的面吹牛氛改,可吹牛的內(nèi)容都是我干的帐萎。 我是一名探鬼主播,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼胜卤,長吁一口氣:“原來是場噩夢啊……” “哼疆导!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起葛躏,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤澈段,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后舰攒,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體败富,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年摩窃,在試婚紗的時候發(fā)現(xiàn)自己被綠了兽叮。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡猾愿,死狀恐怖鹦聪,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情匪蟀,我是刑警寧澤椎麦,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站材彪,受9級特大地震影響观挎,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜段化,卻給世界環(huán)境...
    茶點故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一嘁捷、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧显熏,春花似錦雄嚣、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽鼓鲁。三九已至,卻和暖如春港谊,著一層夾襖步出監(jiān)牢的瞬間骇吭,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工歧寺, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留燥狰,地道東北人。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓斜筐,卻偏偏與公主長得像龙致,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子顷链,可洞房花燭夜當晚...
    茶點故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 1. 定義 模板方法模式:定義一個操作中算法的框架目代,而將一些步驟延遲到子類中。模板方法模式使得子類可以不改變一個算...
    CrixalisAs閱讀 296評論 0 0
  • 1. 定義 定義一個操作的算法骨架嗤练,而將一些步驟延遲到子類中像啼。模板方法使得子類可以不改變一個算法的結(jié)構(gòu),即可重定義...
    落英墜露閱讀 220評論 0 0
  • 模板方法模式:定義一個操作中算法的框架潭苞,而將一些步驟延遲到子類中忽冻。模板方法模式使得子類可以不改變一個算法的結(jié)構(gòu)即可...
    _涼笙閱讀 320評論 0 0
  • 說到模(mú)板,很多人都接觸過此疹,C++和Java都有諸如List和Stack這樣的模板類僧诚。但是說到模板方法,很多...
    Mock2052閱讀 1,096評論 0 1
  • 暑假自駕游上海蝗碎,我一家三口還有侄女毛妮湖笨。南陽上滬陜高速,行至南京已是傍晚蹦骑。手機導(dǎo)航顯示前方堵車五公里慈省,需要繞道南京...
    王新屏閱讀 326評論 0 0