一、先嘮嘮嗑!
之所以想寫這個模板方法設計模式,我想純屬偶然!為什麼呢?因為最近在看關於Spring框架的原始碼,剛開始看有點暈,因為你會被它所有類、介面的繼承關係所迷亂,不過當你知道了它是運用哪種設計模式,那麼我想說再去看原始碼至少輪廓就清晰很多了!
Spring框架用到的設計模式非常地多,比如Resource模組運用了策略模式
,事務模組
運用了模板方法模式等等很多,我說不完,大家可以自行谷哥之。
接下來我就解釋下什麼是模板方法模式,至於它在Spring中的應用,我打算之後再寫出一篇文章來進行總結!
二、什麼是模板方法
設計模式?
模板模式
是一種行為設計模式,它的實現思路是,建立一個模板方法method
,在該模板類中定義一些基本方法供模板方法method
呼叫,這些基本方法通常是protected
修飾的,因為它並不需要對外提供訪問。模板方法method
定義了一個演算法的執行步驟,或者說能夠提供一種預設的實現,這種實現概括一部分子類或者全部子類的共同部分(說白了就是概括了所有子類的共同特性,並且自己實現了它
)。
說到設計模式,不貼張UML圖出來我都覺得不好意思。
看到上面的UML圖,哈哈,不慌,非常地簡單!現在理清下思路,一個最基本的模板方法模式中,你需要建立一個抽象類和一個具體的實現類,從上圖可以看到在抽象類中持有一個模板方法和一些基本方法,而子類只需要對這些基本方法進行實現即可,子類並不需要對模板方法進行實現,因為抽象類已經實現好了!
wokao,賊抽象有木有!下面我就引用一個例子對其進行說明:引用自併發程式設計網
假設提供一種造房子的演算法。演算法的步驟就是模擬造房子的過程:建地基、建支撐,最後新增牆和窗戶
-
- Fundation
-
- Pillars
-
- Walls
-
- 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中用到了