設(shè)計(jì)模式解密(4)- 模板方法模式

平面設(shè)計(jì)培訓(xùn),網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn),美工培訓(xùn),游戲開發(fā),動(dòng)畫培訓(xùn)

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