設(shè)計(jì)模式解密(4)- 模板方法模式
1、簡(jiǎn)介
定義:一個(gè)操作中算法的框架,而將一些步驟延遲到子類中,使得子類可以不改變算法的結(jié)構(gòu)即可重定義該算法中的某些特定步驟。
模板方法模式,一般是為了統(tǒng)一子類的算法實(shí)現(xiàn)步驟,所使用的一種手段或者說是方式。它在父類中定義一系列算法的步驟,而將具體的實(shí)現(xiàn)都推遲到子類。
最典型的形式就是一個(gè)接口,一個(gè)抽象父類,父類中會(huì)有一系列的抽象方法,而在子類中去實(shí)現(xiàn)這些方法。
英文:Template Method
類型:行為類模式
2、實(shí)例引入
背景:學(xué)校老師布置作業(yè),老師布置作業(yè),學(xué)生寫作業(yè),老師檢查作業(yè)
定義一個(gè)抽象作業(yè)類
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | package com.designpattern.templete; /** * 類說明 :學(xué)校教師作業(yè) */ public abstract class Homeork { final void workflow(){ //老師布置作業(yè) this .assginHomework(); //學(xué)生 做 作業(yè) this .doHomework(); //老師檢查作業(yè) this .checkHomework(); } //布置作業(yè) void assginHomework(){ System.out.println( "回家做課后習(xí)題,明天檢查!" ); } //學(xué)生 做 作業(yè) abstract void doHomework(); //檢查作業(yè) void checkHomework(){ System.out.println( "檢查作業(yè)!" ); } } |
A同學(xué)完成寫作業(yè)部分(只關(guān)心寫作業(yè)的部分)
1 2 3 4 5 6 7 8 9 10 11 12 | package com.designpattern.templete; /** * 類說明 :A同學(xué)完成作業(yè)類 */ public class StudentA extends Homeork{ @Override void doHomework() { //TODO 業(yè)務(wù) System.out.println( "A同學(xué)是這樣完成作業(yè)的!" ); } } |
B同學(xué)完成寫作業(yè)部分(只關(guān)心寫作業(yè)的部分)
1 2 3 4 5 6 7 8 9 10 11 12 | package com.designpattern.templete; /** * 類說明 :B同學(xué)完成作業(yè)類 */ public class StudentB extends Homeork{ @Override void doHomework() { // TODO 業(yè)務(wù) System.out.println( "B同學(xué)是這樣完成作業(yè)的!" ); } } |
測(cè)試 A、B同學(xué)完成作業(yè)的過程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | package com.designpattern.templete; /** * 類說明 :測(cè)試 */ public class Test { public static void main(String[] args) { //測(cè)試一次完成作業(yè): 同學(xué)都是怎么樣完成作業(yè)的 StudentA A = new StudentA(); A.workflow(); System.out.println( "---------------------" ); StudentB B = new StudentB(); B.workflow(); } } |
結(jié)果
1 2 3 4 5 6 7 | 回家做課后習(xí)題,明天檢查! A同學(xué)是這樣完成作業(yè)的! 檢查作業(yè)! --------------------- 回家做課后習(xí)題,明天檢查! B同學(xué)是這樣完成作業(yè)的! 檢查作業(yè)! |
3、解決的問題
上面的例子: 學(xué)校作業(yè)的流程都是一樣的,只是學(xué)生做作業(yè)是五花八門的 ,所以把確定的部分提取到抽象父類中,可變的部分有子類完成;
學(xué)生不需要操作怎么布置作業(yè),怎么檢查作業(yè),只需要把自己的任務(wù) --- 寫作業(yè), 完成就行了。
4、應(yīng)用場(chǎng)景
在多個(gè)子類擁有相同的方法,并且這些方法邏輯相同時(shí),可以考慮使用模版方法模式。在程序的主框架相同,細(xì)節(jié)不同的場(chǎng)合下,也比較適合使用這種模式。
引用:大部分剛步入職場(chǎng)的畢業(yè)生應(yīng)該都有類似的經(jīng)歷。一個(gè)復(fù)雜的任務(wù),由公司中的牛人們將主要的邏輯寫好,然后把那些看上去比較簡(jiǎn)單的方法寫成抽象的,交給其他的同事去開發(fā)。這種分工方式在編程人員水平層次比較明顯的公司中經(jīng)常用到。比如一個(gè)項(xiàng)目組,有架構(gòu)師,高級(jí)工程師,初級(jí)工程師,則一般由架構(gòu)師使用大量的接口、抽象類將整個(gè)系統(tǒng)的邏輯串起來(lái),實(shí)現(xiàn)的編碼則根據(jù)難度的不同分別交給高級(jí)工程師和初級(jí)工程師來(lái)完成。怎么樣,是不是用到過模版方法模式?
5、優(yōu)缺點(diǎn)
優(yōu)點(diǎn):
容易擴(kuò)展:一般來(lái)說,抽象類中的模版方法是不易反生改變的部分,而抽象方法是容易反生變化的部分,因此通過增加實(shí)現(xiàn)類一般可以很容易實(shí)現(xiàn)功能的擴(kuò)展,符合開閉原則。
便于維護(hù):對(duì)于模版方法模式來(lái)說,正是由于他們的主要邏輯相同,才使用了模版方法,假如不使用模版方法,任由這些相同的代碼散亂的分布在不同的類中,維護(hù)起來(lái)是非常不方便的。
缺點(diǎn):
子類的實(shí)現(xiàn)也可以影響父類中主邏輯的運(yùn)行,在靈活的同時(shí),由于子類影響到了父類,違反了里氏替換原則,也會(huì)給程序帶來(lái)風(fēng)險(xiǎn)。這就對(duì)抽象類的設(shè)計(jì)有了更高的要求。
6、總結(jié)
一次性實(shí)現(xiàn)一個(gè)算法的不變的部分,并將可變的行為留給子類來(lái)實(shí)現(xiàn);
各子類中公共的行為應(yīng)被提取出來(lái)并集中到一個(gè)公共父類中以避免代碼重復(fù);
控制子類的擴(kuò)展;
在多個(gè)子類擁有相同的方法,并且這些方法邏輯相同時(shí),可以考慮使用模版方法模式。在程序的主框架相同,細(xì)節(jié)不同的場(chǎng)合下,也比較適合使用這種模式。
http://www.cnblogs.com/JsonShare/p/7120451.html