導讀 模板模式在是Spring底層被廣泛的應用,比如事務管理器的實現,JDBC模板的實現。 文章首發於作者的微信公眾號【碼猿技術專欄】 今天就來談談「什麼是模板模式」、「模板模式的優缺點」、「模板模式的簡單演示」、「模板模式在Spring底層的實現」。 什麼是模板模式 模板模式首先要有一個抽象類,這 ...
導讀
- 模板模式在是Spring底層被廣泛的應用,比如事務管理器的實現,JDBC模板的實現。
- 文章首發於作者的微信公眾號【碼猿技術專欄】
- 今天就來談談「什麼是模板模式」、「模板模式的優缺點」、「模板模式的簡單演示」、「模板模式在Spring底層的實現」。
什麼是模板模式
- 模板模式首先要有一個抽象類,這個抽象類公開定義了執行它的方法的方式/模板。它的子類可以按需要重寫方法實現,但調用將以抽象類中定義的方式進行。這種類型的設計模式屬於行為型模式。
- 定義:「定義一個操作中的演算法骨架,而將演算法的一些步驟延遲到子類中,使得子類可以不改變該演算法結構的情況下重定義該演算法的某些特定步驟。」
- 比如在造房子一樣,
地基
,鋪線
,房子戶型
都是一樣的,由開發商決定,但是在交房之後,室內的裝修風格
和場景佈置
卻是由業主決定,在這個場景中,開發商其實就是一個抽象類,地基,鋪線,房子戶型都是可以復用的,但是裝修卻是不可復用的,必須由業主決定,此時的每一個業主的房子就是一個實現的子類。 - 模板方法的實現條件註意:
- 必須是一個抽象類。
- 抽象類有一個模板方法,其中定義了演算法骨架。
- 為了防止惡意操作,模板方法必須加上
final
關鍵詞。 - 模板方法中除了復用的代碼,其他的關鍵代碼必須是抽象的,子類可以繼承實現。
優點
- 它封裝了不變部分,擴展可變部分。它把認為是不變部分的演算法封裝到父類中實現,而把可變部分演算法由子類繼承實現,便於子類繼續擴展。
- 它在父類中提取了公共的部分代碼,便於代碼復用。
- 部分方法是由子類實現的,因此子類可以通過擴展方式增加相應的功能,符合開閉原則。
缺點
- 對每個不同的實現都需要定義一個子類,這會導致類的個數增加,系統更加龐大,設計也更加抽象。
- 父類中的抽象方法由子類實現,子類執行的結果會影響父類的結果,這導致一種反向的控制結構,它提高了代碼閱讀的難度。
簡單演示
- 比如游戲的運行需要如下幾個步驟:上述的三個步驟可以是模板類的抽象方法,由具體的子類實現,比如足球游戲。
- 初始化游戲
- 開始游戲
- 結束游戲
- 定義模板類,必須是一個抽象類,模板方法必須是
final
修飾。
public abstract class Game {
//抽象方法
abstract void initialize();
abstract void startPlay();
abstract void endPlay();
//模板方法
public final void play(){
//初始化游戲
initialize();
//開始游戲
startPlay();
//結束游戲
endPlay();
}
}
- 定義實現類,足球游戲,繼承模板類,實現其中的三個抽象方法
public class Football extends Game {
@Override
void endPlay() {
System.out.println("足球游戲結束......");
}
@Override
void initialize() {
System.out.println("足球游戲初始化中......");
}
@Override
void startPlay() {
System.out.println("足球游俠開始了......");
}
}
- 此時寫一個測試方法,運行足球游戲,如下:
public class TemplatePatternDemo {
public static void main(String[] args) {
//創建足球游戲實例
Game game = new Football();
//開始游戲
game.play();
}
}
- 輸出結果如下:
足球游戲初始化中......
足球游俠開始了......
足球游戲結束......
Spring中的模板模式
- Spring底層對於模板模式的使用有很多處,今天陳某帶大家康康事務管理器是如何使用模板模式的。
模板抽象類
AbstractPlatformTransactionManager
是Spring中的模板抽象類
,來看看它的繼承關係圖:- 實現了
PlatformTransactionManager
介面,重載了介面中的方法。
模板方法
- 事務管理器中抽象類中的模板方法不止一個,比如以下兩個方法
//提交事務
public final void commit()
//獲取TransactionStatus
public final TransactionStatus getTransaction()
- 這兩個方法都對於自己要實現的邏輯搭建了一個骨架,主要的功能是由抽象方法完成,由子類來完成。
抽象方法
- 事務管理器抽象類中的抽象方法定義了多個,分別用於處理不同的業務邏輯,由子類實現其中具體的邏輯,如下:
//提交事務
protected abstract void doCommit(DefaultTransactionStatus status);
//回滾事務
protected abstract void doRollback(DefaultTransactionStatus status);
//開始事務
protected abstract void doBegin(Object transaction, TransactionDefinition definition)
//獲取當前的事務對象
protected abstract Object doGetTransaction()
- 抽象方法的定義便於子類去擴展,在保證演算法邏輯不變的情況下,子類能夠定製自己的實現。
具體子類
- 事務管理器的模板類有很多的具體子類,如下圖:
- 其中我們熟悉的有
DataSourceTransactionManager
、JtaTransactionManager
、RabbitTransactionManager
。具體承擔什麼樣的角色和責任不是本節的重點,不再細說。
總結
- 模板模式是一個很重要,易擴展的模式,提高了代碼復用性,在Spring中有著廣泛的應用,比如
JDBCTemplate
,AbstractPlatformTransactionManager
,這些實現都用到了模板模式。 - 如果覺得陳某的文章能夠對你有所幫助,有所啟發,關註分享一波,點個在看,謝謝支持!!!