模板模式

模板方法模式定義

模板方法模式(Template Method Pattern)定義如下:Define the skeleton of an algorithm in an operation,deferring some steps to subclasses.TemplateMethod lets subclasses redefine certain steps of an algorithm without changing the algorithm'sstructure.(定義一個(gè)操作中的算法的框架虚婿,而將一些步驟延遲到子類中腹暖。使得子類可以不改變一個(gè)算法的結(jié)構(gòu)即可重定義該算法的某些特定步驟凫佛。)

模板方法模式通用類圖

模板方法模式非常簡單乓旗,僅僅使用了Java的繼承機(jī)制嫂拴,但它是一個(gè)應(yīng)用非常廣泛的模式,其中AbstractClass叫做抽象模板徒爹,它的方法分為兩類:

  • 基本方法:
    基本方法也叫基本操作巍实,是由子類實(shí)現(xiàn)的方法,并且在模板方法被調(diào)用东涡。
  • 模板方法:
    可以又一個(gè)或幾個(gè)冯吓,一般是一個(gè)具體的方法,也就是一個(gè)框架疮跑,實(shí)現(xiàn)對基本方法的調(diào)度组贺,完成固定的邏輯。

模板方法可以配合依賴倒置原則(DIP)使用祖娘,模板方法可以由接口定義失尖,基本方法可由抽象模板實(shí)現(xiàn)。

演示代碼

這次我們的任務(wù)是造車渐苏。先按照最一般的經(jīng)驗(yàn)設(shè)計(jì)類圖

悍馬車模類圖

非常簡單的實(shí)現(xiàn)掀潮,悍馬車有兩個(gè)型號,H1和H2整以。按照需求胧辽,只需要悍馬模型,那好我就給你悍馬模型公黑,先寫個(gè)抽象類邑商,然后兩個(gè)不同型號的模型實(shí)現(xiàn)類摄咆,通過簡單的繼承就可以實(shí)現(xiàn)業(yè)務(wù)要求。開始工作人断!

1.抽象悍馬模型

public abstract class HummerModel {
    /*
     * 首先吭从,這個(gè)模型要能夠被發(fā)動(dòng)起來,別管是手搖發(fā)動(dòng)恶迈,還是電力發(fā)動(dòng)涩金,反正 是要能夠發(fā)動(dòng)起來,那這個(gè)實(shí)現(xiàn)要在實(shí)現(xiàn)類里了
     */
    public abstract void start();
    // 能發(fā)動(dòng)暇仲,那還要能停下來步做,那才是真本事
    public abstract void stop(); 
    // 喇叭會出聲音,是滴滴叫奈附,還是嗶嗶叫
    public abstract void alarm();
    // 引擎會轟隆隆的響全度,不響那是假的
    public abstract void engineBoom();
    // 那模型應(yīng)該會跑吧,別管是人推的斥滤,還是電力驅(qū)動(dòng)将鸵,總之要會跑
    public abstract void run();
}

在抽象類中,我們定義了悍馬模型都必須具有的特質(zhì):能夠發(fā)動(dòng)佑颇、停止顶掉,喇叭會響,引擎可以轟鳴挑胸,而且還可以停止痒筒。

  1. H1型號的悍馬
public class HummerH1Model extends HummerModel {
    // H1型號的悍馬車鳴笛
    public void alarm() {
        System.out.println("悍馬H1鳴笛...");
    }
    // 引擎轟鳴聲
    public void engineBoom() {
        System.out.println("悍馬H1引擎聲音是這樣在...");
    }
    // 汽車發(fā)動(dòng)
    public void start() {
        System.out.println("悍馬H1發(fā)動(dòng)...");
    }
    // 停車
    public void stop() {
        System.out.println("悍馬H1停車...");
    }
    // 開動(dòng)起來
    public void run() {
        // 先發(fā)動(dòng)汽車
        this.start();
        // 引擎開始轟鳴
        this.engineBoom();
        // 然后就開始跑了,跑的過程中遇到一條狗擋路嗜暴,就按喇叭
        this.alarm();
        // 到達(dá)目的地就停車
        this.stop();
    } 
}

3.H2型號的悍馬

public class HummerH2Model extends HummerModel {
    // H2型號的悍馬車鳴笛
    public void alarm() {
        System.out.println("悍馬H2鳴笛...");
    }
    // 引擎轟鳴聲
    public void engineBoom() {
        System.out.println("悍馬H2引擎聲音是這樣在...");
    }
    // 汽車發(fā)動(dòng)
    public void start() {
        System.out.println("悍馬H2發(fā)動(dòng)...");
    }
    // 停車
    public void stop() {
        System.out.println("悍馬H2停車...");
    }
    // 開動(dòng)起來
    public void run() {
        // 先發(fā)動(dòng)汽車
        this.start();
        // 引擎開始轟鳴
        this.engineBoom();
        // 然后就開始跑了凸克,跑的過程中遇到一條狗擋路,就按喇叭
        this.alarm();
        // 到達(dá)目的地就停車
        this.stop();
    }
}

4.悍馬的模型是造好了闷沥,能不能造出真的呢萎战??試一試舆逃!

public class Client {
    public static void main(String[] args) {
                HummerH1Model h1 = new HummerH1Model();
        h1.start();
        h1.engineBoom();
        h1.run();
        h1.alarm();
        h1.run();
        h1.stop();
    }
 }

悍馬H1鳴笛...
悍馬H1發(fā)動(dòng)...
悍馬H1引擎聲音是這樣在...
悍馬H1鳴笛...
悍馬H1停車...
悍馬H1停車...

非常簡單蚂维,那如果我告訴你這就是模板方法模式你會不會很不屑呢?就這模式路狮,太簡單了虫啥,我一直在使用呀!是的奄妨,你經(jīng)常在使用涂籽,但你不知道這是模板方法模式,那些所謂的高手就可以很牛地說:“用模板方法模式就可以實(shí)現(xiàn)”砸抛,你還要很崇拜地看著评雌,哇树枫,牛人,模板方法模式是什么呀景东?這就是模板方法模式砂轻。

注意

  • 為了防止惡意的操作,一般模板方法都加上final關(guān)鍵字斤吐,不允許被覆寫搔涝。
  • 抽象模板中的基本方法盡量設(shè)計(jì)為protected類型,符合迪米特法則和措,不需要暴露的屬性或方法盡量不要設(shè)置為protected類型庄呈。實(shí)現(xiàn)類若非必要,盡量不要擴(kuò)大父類中的訪問權(quán)限派阱。

模板方法模式的優(yōu)點(diǎn)

  • 封裝不變部分抒痒,擴(kuò)展可變部分把認(rèn)為是不變部分的算法封裝到父類實(shí)現(xiàn),而可變部分的則可以通過繼承來繼續(xù)擴(kuò)展颁褂。在悍馬模型例子中,是不是就非常容易擴(kuò)展傀广?例如增加一個(gè)H3型號的悍馬模型颁独,很容易呀,增加一個(gè)子類伪冰,實(shí)現(xiàn)父類的基本方法就可以了誓酒。
  • 提取公共部分代碼,便于維護(hù)我們例子中剛剛走過的彎路就是最好的證明贮聂,如果我們不抽取到父類中靠柑,任由這種散亂的代碼發(fā)生,想想后果是什么樣子吓懈?維護(hù)人員為了修正一個(gè)缺陷歼冰,需要到處查找類似的代碼!
  • 行為由父類控制耻警,子類實(shí)現(xiàn)基本方法是由子類實(shí)現(xiàn)的隔嫡,因此子類可以通過擴(kuò)展的方式增加相應(yīng)的功能,符合開閉原則甘穿。

模板方法模式的缺點(diǎn)

按照我們的設(shè)計(jì)習(xí)慣腮恩,抽象類負(fù)責(zé)聲明最抽象、最一般的事物屬性和方法温兼,實(shí)現(xiàn)類完成具體的事物屬性和方法秸滴。但是模板方法模式卻顛倒了,抽象類定義了部分抽象方法募判,由子類實(shí)現(xiàn)荡含,子類執(zhí)行的結(jié)果影響了父類的結(jié)果咒唆,也就是子類對父類產(chǎn)生了影響,這在復(fù)雜的項(xiàng)目中内颗,會帶來代碼閱讀的難度钧排,而且也會讓新手產(chǎn)生不適感。

模板方法模式的使用場景

  • 多個(gè)子類有公有的方法均澳,并且邏輯基本相同時(shí)恨溜。
  • 重要、復(fù)雜的算法找前,可以把核心算法設(shè)計(jì)為模板方法糟袁,周邊的相關(guān)細(xì)節(jié)功能則由各個(gè)
    子類實(shí)現(xiàn)。
  • 重構(gòu)時(shí)躺盛,模板方法模式是一個(gè)經(jīng)常使用的模式项戴,把相同的代碼抽取到父類中,然后通
    過鉤子函數(shù)(見“模板方法模式的擴(kuò)展”)約束其行為槽惫。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末周叮,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子界斜,更是在濱河造成了極大的恐慌仿耽,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件各薇,死亡現(xiàn)場離奇詭異项贺,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)峭判,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進(jìn)店門开缎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人林螃,你說我怎么就攤上這事奕删。” “怎么了疗认?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵急侥,是天一觀的道長。 經(jīng)常有香客問我侮邀,道長坏怪,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任绊茧,我火速辦了婚禮铝宵,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己鹏秋,他們只是感情好尊蚁,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著侣夷,像睡著了一般横朋。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上百拓,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天琴锭,我揣著相機(jī)與錄音,去河邊找鬼衙传。 笑死决帖,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的蓖捶。 我是一名探鬼主播地回,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼俊鱼!你這毒婦竟也來了刻像?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤并闲,失蹤者是張志新(化名)和其女友劉穎绎速,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體焙蚓,經(jīng)...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年洒宝,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了购公。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,133評論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡雁歌,死狀恐怖宏浩,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情靠瞎,我是刑警寧澤比庄,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站乏盐,受9級特大地震影響佳窑,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜父能,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一神凑、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦溉委、人聲如沸鹃唯。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽坡慌。三九已至,卻和暖如春藻三,著一層夾襖步出監(jiān)牢的瞬間洪橘,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工趴酣, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留梨树,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓岖寞,卻偏偏與公主長得像抡四,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子仗谆,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評論 2 355

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