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

在閻宏博士的《JAVA與模式》一書中開頭是這樣描述模板方法(Template Method)模式的:模板方法模式是類的行為模式。準(zhǔn)備一個(gè)抽象類愉豺,將部分邏輯以具體方法以及具體構(gòu)造函數(shù)的形式實(shí)現(xiàn)允乐,然后聲明一些抽象方法來迫使子類實(shí)現(xiàn)剩余的邏輯矮嫉。不同的子類可以以不同的方式實(shí)現(xiàn)這些抽象方法,從而對(duì)剩余的邏輯有不同的實(shí)現(xiàn)牍疏。這就是模板方法模式的用意蠢笋。

在模版方法模式中,通過在模版抽象類中定義一個(gè)操作的算法骨架鳞陨,將一些步驟抽取封裝到具體的抽象方法中昨寞,強(qiáng)迫子類進(jìn)行按需要重寫實(shí)現(xiàn)方法,這樣使得在使用的時(shí)候厦滤,子類可以不改變算法結(jié)構(gòu)即可重新定義算法的特定步驟援岩。模版方法模式是基于繼承代碼復(fù)用的基本技術(shù)。

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

模版方法模式UML

TemplateMethod.png

模版方法模式涉及的角色

  • 抽象模板角色(AbstractTemplate):抽象模版類掏导,用來定義算法的基本骨架享怀,同時(shí)定義一個(gè)或多個(gè)抽象操作,這些操作由子類進(jìn)行實(shí)現(xiàn)趟咆。
  • 具體模板角色(ConcreteTemplate):具體模板角色凹蜈,用來實(shí)現(xiàn)算法骨架中的某些步驟,完成與特定子類相關(guān)的功能忍啸。

案例演示

這里我們以登錄作為一個(gè)演示的例子,我們都知道履植,登錄模塊有會(huì)員登錄和普通用戶登錄计雌,這兩塊在登錄權(quán)限處理上有所不同。

定義抽象模版登錄模塊

/**
 * 聲明一個(gè)抽象模版類
 * @author Iflytek_dsw
 *
 */
abstract class AbstractLogin {
    /**
     * 登錄的過程可以分為以下幾個(gè)步驟:
     * 1玫霎、密碼加密凿滤;
     * 2、用戶驗(yàn)證庶近;
     */
    public void login(String userName, String pwd){
        encryptPwd(pwd);
        loginUser(userName,pwd);
    }
    
    protected abstract void loginUser(String userName, String pwd);
    
    /**
     * 密碼加密
     * @param pwd
     */
    private void encryptPwd(String pwd){
        System.out.println("密碼加密");
    }
}

在抽象登錄模塊中翁脆,我們定義了聲明了一個(gè)方法encryptPwd,同時(shí)聲明了一個(gè)loginUser的抽象函數(shù)鼻种。

定義具體的模板方法類

/**
 * 普通用戶登錄
 * @author Iflytek_dsw
 *
 */
class NormalLogin extends AbstractLogin{

    @Override
    public void loginUser(String userName, String pwd) {
        System.out.println("普通用戶登錄:"+ userName);
    }
}

/**
 * 會(huì)員用戶登錄
 * @author Iflytek_dsw
 *
 */
class MemberLogin extends AbstractLogin{

    @Override
    public void loginUser(String userName, String pwd) {
        System.out.println("會(huì)員用戶登錄" + userName);
    }
}

根據(jù)權(quán)限角色不同反番,登錄的方法有所區(qū)別,即子類重寫父類預(yù)留的模板方法。

客戶端

public class Client {

    /**
     * @param args
     */
    public static void main(String[] args) {
        AbstractLogin normalLogin = new NormalLogin();
        AbstractLogin memberLogin = new MemberLogin();
        
        normalLogin.login("andoter的學(xué)習(xí)筆記", "dsw123");
        memberLogin.login("Andoter學(xué)習(xí)筆記", "andoter123");
    }
}

執(zhí)行結(jié)果

密碼加密
普通用戶登錄
密碼加密
會(huì)員用戶登錄

通過上面的例子罢缸,我們可以看到篙贸,模板方法的核心就是固定算法的骨架結(jié)構(gòu),它的UML圖跟策略模式非常相似枫疆,本質(zhì)上這兩種模式還是有很大差異的爵川。策略模式側(cè)重的不同的策略,模板方法模式側(cè)重的是某個(gè)處理流程中的關(guān)鍵節(jié)點(diǎn)代碼不確定息楔,范圍比策略模式小寝贡。

模板方法中的方法

根據(jù)上面的介紹,模板方法中的方法可以分為兩大類:模板方法和基本方法值依。

模板方法

  • 一個(gè)模板方法是定義在抽象類中的圃泡,把基本操作方法組合在一起形成一個(gè)總算法或一個(gè)總行為的方法。
  • 一個(gè)抽象類可以有任意多個(gè)模板方法鳞滨,而不限于一個(gè)洞焙。每一個(gè)模板方法都可以調(diào)用任意多個(gè)具體方法。

基本方法

  • 抽象方法:一個(gè)抽象方法由抽象類聲明拯啦,由具體子類實(shí)現(xiàn)澡匪。在Java語(yǔ)言里抽象方法以abstract關(guān)鍵字標(biāo)示。
  • 具體方法:一個(gè)具體方法由抽象類聲明并實(shí)現(xiàn)褒链,而子類并不實(shí)現(xiàn)或置換唁情。
  • 鉤子方法:一個(gè)鉤子方法由抽象類聲明并實(shí)現(xiàn),而子類會(huì)加以擴(kuò)展甫匹。通常抽象類給出的實(shí)現(xiàn)是一個(gè)空實(shí)現(xiàn)甸鸟,作為方法的默認(rèn)實(shí)現(xiàn)。

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

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

  • 良好的復(fù)用性兵迅,通過將公共的方法集中在模板類中抢韭,將公共不同部分抽取出來放到子類中實(shí)現(xiàn)達(dá)到復(fù)用的效果。
  • 擴(kuò)展性比較好恍箭,封裝不變的刻恭,擴(kuò)展可變部分。
  • 易于維護(hù)

缺點(diǎn)

  • 骨架固定扯夭,升級(jí)不易鳍贾。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市交洗,隨后出現(xiàn)的幾起案子骑科,更是在濱河造成了極大的恐慌,老刑警劉巖构拳,帶你破解...
    沈念sama閱讀 221,430評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件咆爽,死亡現(xiàn)場(chǎng)離奇詭異梁棠,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)伍掀,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,406評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門掰茶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人蜜笤,你說我怎么就攤上這事濒蒋。” “怎么了把兔?”我有些...
    開封第一講書人閱讀 167,834評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵沪伙,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我县好,道長(zhǎng)围橡,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,543評(píng)論 1 296
  • 正文 為了忘掉前任缕贡,我火速辦了婚禮翁授,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘晾咪。我一直安慰自己收擦,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,547評(píng)論 6 397
  • 文/花漫 我一把揭開白布谍倦。 她就那樣靜靜地躺著塞赂,像睡著了一般。 火紅的嫁衣襯著肌膚如雪昼蛀。 梳的紋絲不亂的頭發(fā)上宴猾,一...
    開封第一講書人閱讀 52,196評(píng)論 1 308
  • 那天,我揣著相機(jī)與錄音叼旋,去河邊找鬼仇哆。 笑死,一個(gè)胖子當(dāng)著我的面吹牛夫植,可吹牛的內(nèi)容都是我干的税产。 我是一名探鬼主播,決...
    沈念sama閱讀 40,776評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼偷崩,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了撞羽?” 一聲冷哼從身側(cè)響起阐斜,我...
    開封第一講書人閱讀 39,671評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎诀紊,沒想到半個(gè)月后谒出,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,221評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,303評(píng)論 3 340
  • 正文 我和宋清朗相戀三年笤喳,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了为居。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,444評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡杀狡,死狀恐怖蒙畴,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情呜象,我是刑警寧澤膳凝,帶...
    沈念sama閱讀 36,134評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站恭陡,受9級(jí)特大地震影響蹬音,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜休玩,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,810評(píng)論 3 333
  • 文/蒙蒙 一著淆、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧拴疤,春花似錦永部、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,285評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至凫佛,卻和暖如春讲坎,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背愧薛。 一陣腳步聲響...
    開封第一講書人閱讀 33,399評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工晨炕, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人毫炉。 一個(gè)月前我還...
    沈念sama閱讀 48,837評(píng)論 3 376
  • 正文 我出身青樓瓮栗,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親瞄勾。 傳聞我的和親對(duì)象是個(gè)殘疾皇子费奸,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,455評(píng)論 2 359

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