設(shè)計(jì)模式——模板方法模式

模板方法模式——《設(shè)計(jì)模式之禪》

例子

悍馬模型抽象接口

// 抽象是所有子類(lèi)的共性封裝
public abstract class HummerModel{
  /**
   * run();
   * 這是一個(gè)匯總的方法
   */
  final  abstract void run(){
    this.start();
    this.engineBoom();
    if(this.isAlarm()){
        this.alarm();
    }
    this.stop();
  }
  //車(chē)輛發(fā)動(dòng)
  protected  abstract void start();
  //車(chē)輛停止
  protected abstract void stop();
  //車(chē)輛鳴叫
  protected abstract void alarm();
  //車(chē)輛加速
  protected abstract void engineBoom();
  //hook函數(shù),約束是否鳴笛
  protected boolean isAlarm(){
    return true;
  }
}
public class HummerH1Model extends HummerModel  {
  private boolean alarmFlag = true;
  protected void alarm(){
    System.out.println("悍馬H1鳴笛");
  }
  protected void start(){
    System.out.println("悍馬H1發(fā)動(dòng)");
  }
  protected void stop(){
    System.out.println("悍馬H1停止");
  }
  protected void engineBoom(){
    System.out.println("引擎聲音");
  }
  //hook函數(shù),重新實(shí)現(xiàn)可以實(shí)現(xiàn)自定義是否鳴笛
  protected boolean isAlarm(){
    return this.alarmFlag;
  }
  // 由客戶(hù)實(shí)現(xiàn)是否鳴笛
  public void setAlarm(boolean isAlarm){
    this.alarmFlag = isAlarm;
  }
}
public class HummerH2Model extends HummerModel  {
  protected void alarm(){
    System.out.println("悍馬H2鳴笛");
  }
  protected void start(){
    System.out.println("悍馬H2發(fā)動(dòng)");
  }
  protected void stop(){
    System.out.println("悍馬H2停止");
  }
  protected void engineBoom(){
    System.out.println("引擎聲音");
  }
  //hook函數(shù)晴埂,重新實(shí)現(xiàn)可以實(shí)現(xiàn)自定義是否鳴笛
  protected boolean isAlarm(){
    return false;
  }
}
public class Client{
  public static void main(String[] args) throws IOException {
    HummerModel h1 = new HummerH1Model();
    h1.run();
    HummerModel h2 = new HummerH2Model();
    h2.run();
  }
}

模板方法模式的定義

Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm' s structure.
定義一個(gè)操作中的算法的框架躏鱼,而將一些步驟延遲到子類(lèi)中剩燥。使得子類(lèi)可以不改變一個(gè)算法的結(jié)構(gòu)即可重定義該算法的某特定步驟

模板方法模式

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

  • 模板方法模式確實(shí)非常簡(jiǎn)單揭保,僅僅使用了java的繼承機(jī)制埃叭,其中睁搭,AbstractClass叫做抽象模板
    • 基本方法:基本方法也叫做基本操作,是由子類(lèi)實(shí)現(xiàn)的方法吱型,并且在模板方法中被調(diào)用
    • 模板方法:可以有一個(gè)或幾個(gè)逸贾,一般是一個(gè)具體方法,也就是一個(gè)框架津滞,實(shí)現(xiàn)對(duì)基本方法的調(diào)度铝侵,完成固定的邏輯
    • 為了安全起見(jiàn),模板方法一般加修飾符:final防止被惡意修改
  • 在類(lèi)圖中有一個(gè)角色:具體模板触徐。ConcreteClass1和ConcreteClass2屬于具體模板咪鲜,實(shí)現(xiàn)父類(lèi)所定義的一個(gè)或多個(gè)抽象方法。也就是父類(lèi)定義的基本方法在子類(lèi)中得以實(shí)現(xiàn)
抽象模板類(lèi)
public abstract class AbstractClass{
  // 基本方法
  protected abstract void doSomething();
  // 基本方法
  protected abstract void doAnything();
  // 模板方法
  public void templateMethod(){
    /**
     * 調(diào)用基本方法撞鹉,完成相關(guān)的邏輯
     */
  }
}
具體模板類(lèi)
  public class ConcreteClass1 extends AbstractClass{
    // 實(shí)現(xiàn)基本方法
    protected void doAnything(){
      // code to do something
    }
    protected void doSomething(){
      // code to do something()
    }
  }
  public class ConcreteClass2 extends AbstractClass{
    // 實(shí)現(xiàn)基本方法
    protected  void doAnything(){
      // code to do something
    }
    protected void doSomething(){
      // code to do something()
    }
  }
場(chǎng)景類(lèi)
public class Client{
  public static void main(String[] args) {
    AbstractClass class1 = new ConcreteClass1();
    AbstractClass class2 = new ConcreteClass2();
    // 調(diào)用模板方法
    class1.templateMethod();
    class2.templateMethod();
  }
}
注意事項(xiàng)
  • 抽象模板中的基本方法盡量設(shè)計(jì)為protected類(lèi)型疟丙,符合迪米特法則颖侄。不需要暴露的屬性或方法盡量不要設(shè)置為protected屬性
  • 實(shí)現(xiàn)類(lèi)若非必要,盡量不要擴(kuò)大父類(lèi)的訪(fǎng)問(wèn)權(quán)限

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

模板方法模式的優(yōu)點(diǎn)
  • 封裝不變部分享郊,擴(kuò)展可變部分

  • 提取公共部分代碼览祖,便于維護(hù)

  • 行為由父類(lèi)控制,子類(lèi)實(shí)現(xiàn)炊琉。

    基本方法是由子類(lèi)實(shí)現(xiàn)的展蒂,因此子類(lèi)可以通過(guò)擴(kuò)展的方法增加相應(yīng)的功能,符合開(kāi)閉原則

模板方法模式的缺點(diǎn)
  • 模板方法模式抽象類(lèi)定義了部分抽象方法温自,由子類(lèi)實(shí)現(xiàn)玄货,子類(lèi)執(zhí)行的結(jié)果對(duì)父類(lèi)產(chǎn)生了影響皇钞,會(huì)帶來(lái)代碼閱讀的難度

模板方法模式的適用場(chǎng)景

  • 多個(gè)子類(lèi)有公有的方法悼泌,并且邏輯基本相同時(shí)
  • 重要、復(fù)雜的算法夹界,可以把核心算法設(shè)計(jì)為模板方法馆里,周邊的相關(guān)細(xì)節(jié)功能則由各個(gè)子類(lèi)實(shí)現(xiàn)
  • 重構(gòu)時(shí),模板方法模式是一個(gè)經(jīng)常使用的模式可柿,把相同的代碼抽取到父類(lèi)中鸠踪,然后通過(guò)hook函數(shù)約束行為

擴(kuò)展:父類(lèi)調(diào)用子類(lèi)的方法

  • 把父類(lèi)傳遞到子類(lèi)的有參構(gòu)造中,然后調(diào)用
  • 使用反射的方式調(diào)用
  • 父類(lèi)調(diào)用子類(lèi)的靜態(tài)方法
  • 模板方法模式:修改子類(lèi)的方法复斥,影響父類(lèi)的行為
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末营密,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子目锭,更是在濱河造成了極大的恐慌评汰,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,122評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件痢虹,死亡現(xiàn)場(chǎng)離奇詭異被去,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)奖唯,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)惨缆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人丰捷,你說(shuō)我怎么就攤上這事坯墨。” “怎么了病往?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,491評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵畅蹂,是天一觀(guān)的道長(zhǎng)。 經(jīng)常有香客問(wèn)我荣恐,道長(zhǎng)液斜,這世上最難降的妖魔是什么累贤? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,636評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮少漆,結(jié)果婚禮上臼膏,老公的妹妹穿的比我還像新娘。我一直安慰自己示损,他們只是感情好渗磅,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,676評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著检访,像睡著了一般始鱼。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上脆贵,一...
    開(kāi)封第一講書(shū)人閱讀 51,541評(píng)論 1 305
  • 那天医清,我揣著相機(jī)與錄音,去河邊找鬼卖氨。 笑死会烙,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的筒捺。 我是一名探鬼主播柏腻,決...
    沈念sama閱讀 40,292評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼系吭!你這毒婦竟也來(lái)了五嫂?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,211評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤肯尺,失蹤者是張志新(化名)和其女友劉穎沃缘,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體蟆盹,經(jīng)...
    沈念sama閱讀 45,655評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡孩灯,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,846評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了逾滥。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片峰档。...
    茶點(diǎn)故事閱讀 39,965評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖寨昙,靈堂內(nèi)的尸體忽然破棺而出讥巡,到底是詐尸還是另有隱情,我是刑警寧澤舔哪,帶...
    沈念sama閱讀 35,684評(píng)論 5 347
  • 正文 年R本政府宣布欢顷,位于F島的核電站,受9級(jí)特大地震影響捉蚤,放射性物質(zhì)發(fā)生泄漏抬驴。R本人自食惡果不足惜炼七,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,295評(píng)論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望布持。 院中可真熱鬧豌拙,春花似錦、人聲如沸题暖。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,894評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)胧卤。三九已至唯绍,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間枝誊,已是汗流浹背况芒。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,012評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留侧啼,地道東北人牛柒。 一個(gè)月前我還...
    沈念sama閱讀 48,126評(píng)論 3 370
  • 正文 我出身青樓堪簿,卻偏偏與公主長(zhǎng)得像痊乾,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子椭更,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,914評(píng)論 2 355

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

  • 目錄 本文的結(jié)構(gòu)如下: 引言 什么是模板方法模式 模式的結(jié)構(gòu) 代碼示例 優(yōu)點(diǎn)和缺點(diǎn) 適用環(huán)境 模式應(yīng)用 一哪审、引言 ...
    w1992wishes閱讀 805評(píng)論 0 3
  • TEMPLATE METHOD(模板方法) ———— 類(lèi)行為型模式 意圖 定義一個(gè)操作中的算法骨架,而將一些步驟延...
    tomas家的小撥浪鼓閱讀 1,164評(píng)論 0 2
  • 定義 模板方法模式是類(lèi)的行為模式虑瀑。準(zhǔn)備一個(gè)抽象類(lèi)湿滓,將部分邏輯以具體方法以及具體構(gòu)造函數(shù)的形式實(shí)現(xiàn),然后聲明一些抽象...
    步積閱讀 883評(píng)論 0 0
  • 本來(lái)想學(xué)習(xí)spring源碼的舌狗,但現(xiàn)在的水平去讀它感覺(jué)太難了叽奥,還是先學(xué)習(xí)一些設(shè)計(jì)模式(畢竟開(kāi)源框架中使用了很多的設(shè)計(jì)...
    何甜甜在嗎閱讀 641評(píng)論 0 0
  • 一葉載去滿(mǎn)目秋 春歸何處憶歲舊 兩言三語(yǔ)誰(shuí)夢(mèng)里 枯井望穿四時(shí)流 淺雪不如傷情淚 笑魘哪知嘆時(shí)愁 寧得西嶺一片月 莫...
    遠(yuǎn)銘閱讀 216評(píng)論 0 3