談一談我對‘模板方法’設計模式的理解(Template)

擁抱心中的夢想發表於2018-03-21

一、先嘮嘮嗑!

之所以想寫這個模板方法設計模式,我想純屬偶然!為什麼呢?因為最近在看關於Spring框架的原始碼,剛開始看有點暈,因為你會被它所有類、介面的繼承關係所迷亂,不過當你知道了它是運用哪種設計模式,那麼我想說再去看原始碼至少輪廓就清晰很多了!

Spring框架用到的設計模式非常地多,比如Resource模組運用了策略模式事務模組運用了模板方法模式等等很多,我說不完,大家可以自行谷哥之。

接下來我就解釋下什麼是模板方法模式,至於它在Spring中的應用,我打算之後再寫出一篇文章來進行總結!

二、什麼是模板方法設計模式?

模板模式是一種行為設計模式,它的實現思路是,建立一個模板方法method,在該模板類中定義一些基本方法供模板方法method呼叫,這些基本方法通常是protected修飾的,因為它並不需要對外提供訪問。模板方法method定義了一個演算法的執行步驟,或者說能夠提供一種預設的實現,這種實現概括一部分子類或者全部子類的共同部分(說白了就是概括了所有子類的共同特性,並且自己實現了它)。

說到設計模式,不貼張UML圖出來我都覺得不好意思。

談一談我對‘模板方法’設計模式的理解(Template)

看到上面的UML圖,哈哈,不慌,非常地簡單!現在理清下思路,一個最基本的模板方法模式中,你需要建立一個抽象類和一個具體的實現類,從上圖可以看到在抽象類中持有一個模板方法和一些基本方法,而子類只需要對這些基本方法進行實現即可,子類並不需要對模板方法進行實現,因為抽象類已經實現好了!

wokao,賊抽象有木有!下面我就引用一個例子對其進行說明:引用自併發程式設計網

假設提供一種造房子的演算法。演算法的步驟就是模擬造房子的過程:建地基、建支撐,最後新增牆和窗戶

    1. Fundation
    1. Pillars
    1. Walls
    1. Windows。

最重要的一點就是不能改變此建造過程(也就是我們不能修改或者重寫模板方法的意思),比如不可能在沒用地基的時候就開始建造窗戶吧!如果可以,那簡直是胡扯!。這個例子中,我們就建立了一個模板方法 – 將使用不同的方法完成對房子的建造。

為了確保子類不能重寫(override)這個模板方法,應當使用final。

HouseTemple.java(這個對應我們上面UML圖中的AbstractClass)

package com.journaldev.design.template;
//抽象類
public abstract class HouseTemplate {

    //這是我們的模板方法,子類不能重寫
    public final void buildHouse(){
        buildFoundation();//第一步:建造地基
        buildPillars();//第二步,建造支撐
        buildWalls();//第三步,建造牆
        buildWindows();//第四步,建造窗戶
        System.out.println("House is built.");
    }

    //這個步驟可以預設實現,原文是private修飾,那麼就是說我規定死啦,這個步驟只能這樣實現了,但為了易擴充套件,還是protected OK點
    protected void buildWindows() {
        System.out.println("Building Glass Windows");
    }
    
    //被子類實現的方法
    protected abstract void buildWalls();
    protected abstract void buildPillars();
    
    protected void buildFoundation() {
        System.out.println("Building foundation with cement,iron rods and sand");
    }
}
複製程式碼

下面就寫下具體的實現類:

WoodenHouse.java

package com.journaldev.design.template;

public class WoodenHouse extends HouseTemplate {

    @Override
    public void buildWalls() {
        System.out.println("Building Wooden Walls");
    }
    
    @Override
    public void buildPillars() {
        System.out.println("Building Pillars with Wood coating");
    }
}
複製程式碼

GlassHouse.java

package com.journaldev.design.template;</code>

public class GlassHouse extends HouseTemplate {

    @Override
    public void buildWalls() {
        System.out.println("Building Glass Walls");
    }

    @Override
    public void buildPillars() {
        System.out.println("Building Pillars with glass coating");
    }
}
複製程式碼

使用模板方法:

package com.journaldev.design.template;

public class HousingClient {

    public static void main(String[] args) {
        //建立一個模板,子類由WoodenHouse實現
        HouseTemplate houseType = new WoodenHouse();

        houseType.buildHouse();//呼叫模板方法
        System.out.println("************");
        //建立一個模板,子類由GlassHouse實現
        houseType = new GlassHouse();
        houseType.buildHouse();//呼叫模板方法
    }
}
複製程式碼

三、模板方法設計模式的特點

  • 1、模板方法不能被子類重寫,可用final修飾
  • 2、一個模板方法有確定的步驟組成,這些步驟可以被不同的子類實現,也可以自己實現

四、模板方法設計模式應用場景

  • 1、對於一個業務方法步驟固定,但這些步驟可以有不同的實現情況下
  • 2、Spring JdbcTemplate、Spring Transaction中用到了

相關文章