設(shè)計(jì)模式(九)模版方法模式

1.模版方法模式簡介

模版方法模式介紹

在軟件開發(fā)中,有時(shí)會(huì)遇到類似的情況,某個(gè)方法的實(shí)現(xiàn)需要多個(gè)步驟笙纤,其中有些步驟是固定的,而有些步驟并不固定组力,存在可變性省容。為了提高代碼的復(fù)用性和系統(tǒng)的靈活性,可以使用模板方法模式來應(yīng)對這類情況燎字。

模版方法模式定義

定義一個(gè)操作中的算法框架腥椒,而將一些步驟延遲到子類中阿宅,使得子類可以不改變一個(gè)算法的結(jié)構(gòu)即可重定義算法的某些特定步驟。

模版方法模式結(jié)構(gòu)圖

  • AbstractClass:抽象類笼蛛,定義了一套算法洒放。
  • ConcreteClass:具體實(shí)現(xiàn)類。

2.模版方法模式的簡單實(shí)現(xiàn)

延續(xù)著上一篇設(shè)計(jì)模式(八)外觀模式的寫法滨砍,我們?nèi)耘f來舉一個(gè)武俠的例子往湿,原諒博主是一個(gè)武俠迷。

創(chuàng)建抽象類惋戏,定義算法框架

一個(gè)武俠要戰(zhàn)斗的時(shí)候领追,也有一套固定的通用模式,那就是運(yùn)行內(nèi)功响逢、開通經(jīng)脈绒窑、準(zhǔn)備武器和使用招式,我們把這些用代碼表示就是:

public abstract class AbstractSwordsman {
  //該方法為final舔亭,防止算法框架被覆寫
  public final void fighting(){
      //運(yùn)行內(nèi)功些膨,抽象方法
      neigong();
      //調(diào)整經(jīng)脈,具體方法
      meridian();
      //如果有武器則準(zhǔn)備武器
      if(hasWeapons()) {
          weapons();
      }
      //使用招式
      moves();
      //鉤子方法
      hook();
  }
    //空實(shí)現(xiàn)方法
    protected void hook(){}
    protected abstract void neigong();
    protected abstract void weapons();
    protected abstract void moves();
    protected void meridian(){
        System.out.println("開通正經(jīng)與奇經(jīng)");
    }

    /**
     * 是否有武器,默認(rèn)是有武器的钦铺,鉤子方法
     * @return
     */
    protected boolean hasWeapons(){
         return true;
    }
}

需要注意的是這個(gè)抽象類包含了三種類型的方法订雾,分別是抽象方法、具體方法和鉤子方法矛洞。抽象方法是交由子類去實(shí)現(xiàn)葬燎,具體方法則在父類實(shí)現(xiàn)了子類公共的方法實(shí)現(xiàn),在上面的例子就是武俠開通經(jīng)脈的方式都一樣缚甩,所以就在具體方法中實(shí)現(xiàn)。鉤子方法則分為兩類窑邦,第一類是15行擅威,它有一個(gè)空實(shí)現(xiàn)的方法,子類可以視情況來決定是否要覆蓋它冈钦;第二類則是第9行郊丛,這類鉤子方法的返回類型通常是bool類型的,一般用于對某個(gè)條件進(jìn)行判斷瞧筛,如果條件滿足則執(zhí)行某一步驟厉熟,否則將不執(zhí)行。

定義具體實(shí)現(xiàn)類

本文就拿張無忌较幌、張三豐來作為例子:

public class ZhangWuJi extends AbstractSwordsman {

    @Override
    protected void neigong() {
        System.out.println("運(yùn)行九陽神功");
    }

    @Override
    protected void weapons() {
    }

    @Override
    protected void moves() {
        System.out.println("使用招式乾坤大挪移");
    }

    @Override
    protected boolean hasWeapons() {
        return false;
    }
}

張無忌沒有武器所以hasWeapons方法返回false揍瑟,這樣也不會(huì)走weapons方法了。

public class ZhangSanFeng extends AbstractSwordsman {

    @Override
    protected void neigong() {
        System.out.println("運(yùn)行純陽無極功");
    }

    @Override
    protected void weapons() {
        System.out.println("使用真武劍");
    }

    @Override
    protected void moves() {
        System.out.println("使用招式神門十三劍");
    }

    @Override
    protected void hook() {
        System.out.println("突然肚子不舒服乍炉,老夫先去趟廁所");
    }
}

最后張三豐突然肚子不舒服所以就實(shí)現(xiàn)了鉤子方法hook绢片。

客戶端調(diào)用

public class Client {
    public static void main(String[] args) {
        ZhangWuJi zhangWuJi=new ZhangWuJi();
        zhangWuJi.fighting();
        ZhangSanFeng zhangSanFeng=new ZhangSanFeng();
        zhangSanFeng.fighting();
    }
}

運(yùn)行結(jié)果:
運(yùn)行九陽神功
開通正經(jīng)與奇經(jīng)
使用招式乾坤大挪移
運(yùn)行純陽無極功
開通正經(jīng)與奇經(jīng)
使用真武劍
使用招式神門十三劍
突然肚子不舒服滤馍,老夫先去趟廁所

4.模版方法模式的優(yōu)缺點(diǎn)和使用場景

優(yōu)點(diǎn)

  • 模板方法模式通過把不變的行為搬移到超類,去除了子類中的重復(fù)代碼底循。
  • 子類實(shí)現(xiàn)算法的某些細(xì)節(jié)巢株,有助于算法的擴(kuò)展。

缺點(diǎn)

  • 每個(gè)不同的實(shí)現(xiàn)都需要定義一個(gè)子類熙涤,這會(huì)導(dǎo)致類的個(gè)數(shù)的增加阁苞,設(shè)計(jì)更加抽象。

使用場景

  • 各子類中公共的行為應(yīng)被提取出來并集中到一個(gè)公共父類中以避免代碼重復(fù)祠挫。
  • 面對重要復(fù)雜的算法那槽,可以把核心算法設(shè)計(jì)為模版方法,周邊相關(guān)細(xì)節(jié)功能則有各個(gè)子類實(shí)現(xiàn)茸歧。
  • 需要通過子類來決定父類算法中某個(gè)步驟是否執(zhí)行倦炒,實(shí)現(xiàn)子類對父類的反向控制。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末软瞎,一起剝皮案震驚了整個(gè)濱河市逢唤,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌涤浇,老刑警劉巖鳖藕,帶你破解...
    沈念sama閱讀 216,651評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異只锭,居然都是意外死亡著恩,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評論 3 392
  • 文/潘曉璐 我一進(jìn)店門蜻展,熙熙樓的掌柜王于貴愁眉苦臉地迎上來喉誊,“玉大人,你說我怎么就攤上這事纵顾∥榍眩” “怎么了?”我有些...
    開封第一講書人閱讀 162,931評論 0 353
  • 文/不壞的土叔 我叫張陵施逾,是天一觀的道長敷矫。 經(jīng)常有香客問我,道長汉额,這世上最難降的妖魔是什么曹仗? 我笑而不...
    開封第一講書人閱讀 58,218評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮蠕搜,結(jié)果婚禮上怎茫,老公的妹妹穿的比我還像新娘。我一直安慰自己妓灌,他們只是感情好遭居,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,234評論 6 388
  • 文/花漫 我一把揭開白布啼器。 她就那樣靜靜地躺著,像睡著了一般俱萍。 火紅的嫁衣襯著肌膚如雪端壳。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,198評論 1 299
  • 那天枪蘑,我揣著相機(jī)與錄音损谦,去河邊找鬼。 笑死岳颇,一個(gè)胖子當(dāng)著我的面吹牛照捡,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播话侧,決...
    沈念sama閱讀 40,084評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼栗精,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了瞻鹏?” 一聲冷哼從身側(cè)響起悲立,我...
    開封第一講書人閱讀 38,926評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎新博,沒想到半個(gè)月后薪夕,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,341評論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡赫悄,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,563評論 2 333
  • 正文 我和宋清朗相戀三年原献,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片埂淮。...
    茶點(diǎn)故事閱讀 39,731評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡姑隅,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出倔撞,到底是詐尸還是另有隱情粤策,我是刑警寧澤,帶...
    沈念sama閱讀 35,430評論 5 343
  • 正文 年R本政府宣布误窖,位于F島的核電站,受9級特大地震影響秩贰,放射性物質(zhì)發(fā)生泄漏霹俺。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,036評論 3 326
  • 文/蒙蒙 一毒费、第九天 我趴在偏房一處隱蔽的房頂上張望丙唧。 院中可真熱鬧,春花似錦觅玻、人聲如沸想际。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽胡本。三九已至牌柄,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間侧甫,已是汗流浹背珊佣。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留披粟,地道東北人咒锻。 一個(gè)月前我還...
    沈念sama閱讀 47,743評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像守屉,于是被迫代替她去往敵國和親惑艇。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,629評論 2 354

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