設(shè)計模式——使用模板方法模式盡量減少重復(fù)相似的代碼段

引言

無論是現(xiàn)實(shí)生活還是實(shí)際開發(fā)中旁趟,我們常常會遇到一類相似的行為浦楣,他們都包含相似的基本操作和固定的流程汁汗,不同的是他們在不同的業(yè)務(wù)場景下,這些基本操作的具體實(shí)現(xiàn)有所不同妇斤,但是執(zhí)行流程模式都是相同摇锋,當(dāng)然最簡單的話我們針對不同的業(yè)務(wù)區(qū)實(shí)現(xiàn)對應(yīng)的基本操作丹拯,但那是很low的,代碼質(zhì)量堪憂荸恕,明明是重復(fù)的代碼就沒有必要存在了乖酬,模板方法模式就是解決這樣的問題,同時還可以讓后面接手的開發(fā)同學(xué)用最少的代碼融求、最簡單的方式來復(fù)用并實(shí)現(xiàn)更多的業(yè)務(wù)咬像。

一、模板方法概述

模板方法模式是一種類的行為型模式生宛,在它的結(jié)構(gòu)圖中只有類之間的繼承關(guān)系县昂,沒有對象關(guān)聯(lián)關(guān)系,模板方法模式(Template Method Pattern)官方定義:定義一個操作中的算法的框架陷舅,而將一些步驟延遲到子類中倒彰,使得子類可以不改變一個算法的結(jié)構(gòu)即可重定義該算法的某些特定步驟。(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.)是不是很裝X莱睁,通俗來說模板方法模式本質(zhì)僅僅是使用了Java的繼承機(jī)制待讳,封裝幾個抽象方法和一個具體模板方法。模板方法模式中作為父類的抽象類叫做抽象模板AbstractClass仰剿,抽象模板中的基本方法盡量設(shè)計為protected類型创淡,符合迪米特法則,不需要暴露的屬性或方法盡量不要設(shè)置為protected類型南吮。實(shí)現(xiàn)類若非必要辩昆,盡量不要擴(kuò)大父類中的訪問權(quán)限;繼承抽象模板的就叫做具體模板旨袒,抽象模板中包含三種類型的方法: 基本方法汁针、模板方法鉤子方法(Hook Method)。

  • 基本方法——基本方法也叫做基本操作砚尽,是由子類實(shí)現(xiàn)的方法施无,并且在模板方法被調(diào)用。

  • 模板方法——核心方法必孤,不允許子類重寫猾骡,所以都會加上final修飾符,可以有一個或幾個敷搪,一般是一個具體方法框架兴想,按照固定的流程對基本方法的調(diào)度

  • 鉤子方法——為了讓模板方法的執(zhí)行結(jié)果的更好地適應(yīng)因外界條件改變。比如說銀行辦理業(yè)務(wù)為例赡勘,辦理業(yè)務(wù)是個模板方法嫂便,普通人要經(jīng)歷排隊、取號闸与、等待毙替、辦理四個基本流程岸售,而Vip則不需要排隊、取號厂画、等待凸丸,那么在設(shè)計的時候我們的抽象模板類需要考慮到,于是乎你得需要在模板方法各基本方法調(diào)用之前增加條件判斷袱院,那么用于設(shè)置這個條件的方法就是屎慢,鉤子方法(Hook Method),鉤子方法也可以是抽象的還可以由子類的一個方法返回值決定公共部分的執(zhí)行結(jié)果忽洛。

二腻惠、模板方法的優(yōu)點(diǎn)和缺點(diǎn)及常見可用場景

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

  • 良好的擴(kuò)展性脐瑰,封裝不變部分妖枚,擴(kuò)展可變部分,把認(rèn)為是不變部分的算法封裝到父類實(shí)現(xiàn)苍在,而可變部分的則可以通過繼承來繼續(xù)擴(kuò)展绝页。例如增加一個新的功能很簡單,只要再增加一個子類寂恬,實(shí)現(xiàn)父類的基本方法就可以了续誉。

  • 提取公共部分代碼,便于維護(hù)初肉,減小維護(hù)升級成本酷鸦,基本操作由父類定義,子類實(shí)現(xiàn)

  • 基本方法是由子類實(shí)現(xiàn)的牙咏,因此子類可以通過擴(kuò)展的方式增加相應(yīng)的功能臼隔,符合開閉原 則。

2妄壶、模板方法模式的缺點(diǎn)

通常抽象類是負(fù)責(zé)聲明某一類的事物的共同屬性和抽象方法摔握,實(shí)現(xiàn)類則是完成定義具體的特性和方法。但是模板方法模式卻顛倒了丁寄,抽象類定義了部分抽象方法氨淌,由子類實(shí)現(xiàn),子類執(zhí)行的結(jié)果影響了父類的結(jié)果伊磺,也就是子類對父類產(chǎn)生了影響盛正,可能會讓新手產(chǎn)生不適感,以下不理解代碼屑埋。

3豪筝、適合使用模板方法模式的場景

  • 多個子類有公有的方法,并且邏輯基本相同時。

  • 重要壤蚜、復(fù)雜的算法即寡,可以把核心算法設(shè)計為模板方法碘饼,周邊的相關(guān)細(xì)節(jié)功能則由各個 子類實(shí)現(xiàn)顶吮。

  • 重構(gòu)時横堡,模板方法模式是一個經(jīng)常使用的模式,把相同的代碼抽取到父類中著蟹,然后通過鉤子方法約束其行為。

三梢莽、模板方法的實(shí)現(xiàn)

如下圖所示模板方法模式很簡單萧豆,通俗來說模板方法本質(zhì)上封裝了一個固定的工作流程,相似的一類事務(wù)都按照固定的流程來執(zhí)行昏名,整個結(jié)構(gòu)就全部在一個抽象模板類里


這里寫圖片描述

前面所說模板方法模式是基于繼承的代碼復(fù)用基本技術(shù)涮雷,在模板方法模式中,可以將相同的代碼放在父類中轻局,而將不同的方法實(shí)現(xiàn)放在不同的子類中洪鸭。所以實(shí)現(xiàn)起來步驟很簡單:

1、定義抽象模板類

將部分邏輯以具體方法以及具體構(gòu)造函數(shù)的形式實(shí)現(xiàn)仑扑,然后聲明一些抽象方法來讓子類實(shí)現(xiàn)剩余的邏輯览爵,并且定義鉤子方法控制基本方法的執(zhí)行。

public abstract class AbstractClass {
    //基本方法1
    protected abstract void doOneStep();
    //基本方法2
    protected abstract void doSecStep();
    //基本方法3
    protected abstract void doThirdStep();
    
    //模板方法,為了避免被子類覆寫改變模板方法的算法骨架一般使用final修飾镇饮,可以有N個模板方法
    public final void work(){
        /*
        * 調(diào)用基本方法蜓竹,完成相關(guān)的邏輯
        */
        if(oneStepNeedRun){//鉤子方法控制基本方法是否執(zhí)行
            this.doOneStep();
        }
        this.doSecStep();
        
        this.doThirdStep();
    }
    
    //鉤子方法它在抽象類中不做事或者是默認(rèn)的事情,子類可以選擇覆蓋它储藐,可以有N個
    protected boolean oneStepNeedRun(){
        return true;
    }
}

2俱济、繼承抽象模板類實(shí)現(xiàn)具體模板類

就是普通的繼承,根據(jù)各自的業(yè)務(wù)需要可以選擇是否覆寫鉤子方法的實(shí)現(xiàn)邏輯钙勃。

public class ConcreteClass extends AbstractClass {
    //實(shí)現(xiàn)基本方法
    protected void doOneStep() {
    //業(yè)務(wù)邏輯處理
    }
    protected void doSecStep() {
    //業(yè)務(wù)邏輯處理
    }
    protected void doThirdStep() {
    //業(yè)務(wù)邏輯處理
    }
    
}

測試

public class TemplateMethod {
    public static void main(String[] args) {
        AbstractClass obj = new ConcreteClass();//多態(tài)構(gòu)建
        //調(diào)用模板方法
        obj.work();
    }
}

小結(jié)

  • 模板方法模式是一種類的行為型模式蛛碌,在它的結(jié)構(gòu)圖中只有類之間的繼承關(guān)系,沒有對象關(guān)聯(lián)關(guān)系肺缕。

  • 模板方法模式是基于繼承和多態(tài)的代碼復(fù)用基本技術(shù)

  • 在模板方法模式中左医,將固定的相同的功能的代碼段放在父類并在父類中實(shí)現(xiàn),而將需要根據(jù)業(yè)務(wù)而各自實(shí)現(xiàn)的方法統(tǒng)一抽象到父類而把實(shí)現(xiàn)延遲到不同的子類中同木。

  • 在模板方法模式中浮梢,結(jié)構(gòu)很簡單一個抽象類和若干個具體實(shí)現(xiàn)子類,抽象類即抽象模板只是定義了基本的操作方法(抽象模板中的基本方法盡量設(shè)計為protected類型彤路,符合迪米特法則秕硝,不需要暴露
    的屬性或方法盡量不要設(shè)置為protected類型。實(shí)現(xiàn)類若非必要洲尊,盡量不要擴(kuò)大父類中的訪問
    權(quán)限远豺。)而把實(shí)現(xiàn)延遲到子類中實(shí)現(xiàn)奈偏、以及實(shí)現(xiàn)了用于規(guī)范基本方法調(diào)用流程的模板方法(一般將模板方法聲明為final),最后還可以根據(jù)具體的業(yè)務(wù)區(qū)定義鉤子方法用于控制基本方法的執(zhí)行躯护。

  • 最后策略模式和模板方法模式都是用于封裝算法惊来,前者是利用組合和委托模型,而后者則是繼承棺滞。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末裁蚁,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子继准,更是在濱河造成了極大的恐慌枉证,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,997評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件移必,死亡現(xiàn)場離奇詭異室谚,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)崔泵,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評論 3 392
  • 文/潘曉璐 我一進(jìn)店門秒赤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人管削,你說我怎么就攤上這事倒脓。” “怎么了含思?”我有些...
    開封第一講書人閱讀 163,359評論 0 353
  • 文/不壞的土叔 我叫張陵崎弃,是天一觀的道長。 經(jīng)常有香客問我含潘,道長饲做,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,309評論 1 292
  • 正文 為了忘掉前任遏弱,我火速辦了婚禮盆均,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘漱逸。我一直安慰自己泪姨,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,346評論 6 390
  • 文/花漫 我一把揭開白布饰抒。 她就那樣靜靜地躺著肮砾,像睡著了一般。 火紅的嫁衣襯著肌膚如雪袋坑。 梳的紋絲不亂的頭發(fā)上仗处,一...
    開封第一講書人閱讀 51,258評論 1 300
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼婆誓。 笑死吃环,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的洋幻。 我是一名探鬼主播郁轻,決...
    沈念sama閱讀 40,122評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼鞋屈!你這毒婦竟也來了范咨?” 一聲冷哼從身側(cè)響起故觅,我...
    開封第一講書人閱讀 38,970評論 0 275
  • 序言:老撾萬榮一對情侶失蹤厂庇,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后输吏,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體权旷,經(jīng)...
    沈念sama閱讀 45,403評論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,596評論 3 334
  • 正文 我和宋清朗相戀三年贯溅,在試婚紗的時候發(fā)現(xiàn)自己被綠了拄氯。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,769評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡它浅,死狀恐怖译柏,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情姐霍,我是刑警寧澤鄙麦,帶...
    沈念sama閱讀 35,464評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站镊折,受9級特大地震影響胯府,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜恨胚,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,075評論 3 327
  • 文/蒙蒙 一骂因、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧赃泡,春花似錦寒波、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,705評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至僚碎,卻和暖如春猴娩,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,848評論 1 269
  • 我被黑心中介騙來泰國打工卷中, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留矛双,地道東北人。 一個月前我還...
    沈念sama閱讀 47,831評論 2 370
  • 正文 我出身青樓蟆豫,卻偏偏與公主長得像议忽,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子十减,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,678評論 2 354

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