導讀

  • 模板模式在是Spring底層被廣泛的應用,比如事務管理器的實現,JDBC模板的實現。
  • 文章首發於作者的微信公眾號【碼猿技術專欄】
  • 今天就來談談「什麼是模板模式」、「模板模式的優缺點」、「模板模式的簡單演示」、「模板模式在Spring底層的實現」。

什麼是模板模式

  • 模板模式首先要有一個抽象類,這個抽象類公開定義了執行它的方法的方式/模板。它的子類可以按需要重寫方法實現,但呼叫將以抽象類中定義的方式進行。這種型別的設計模式屬於行為型模式。
  • 定義:「定義一個操作中的演算法骨架,而將演算法的一些步驟延遲到子類中,使得子類可以不改變該演算法結構的情況下重定義該演算法的某些特定步驟。」
  • 比如在造房子一樣,地基鋪線房子戶型都是一樣的,由開發商決定,但是在交房之後,室內的裝修風格場景佈置卻是由業主決定,在這個場景中,開發商其實就是一個抽象類,地基,鋪線,房子戶型都是可以複用的,但是裝修卻是不可複用的,必須由業主決定,此時的每一個業主的房子就是一個實現的子類。
  • 模板方法的實現條件注意:
    1. 必須是一個抽象類。
    2. 抽象類有一個模板方法,其中定義了演算法骨架。
    3. 為了防止惡意操作,模板方法必須加上final關鍵詞。
    4. 模板方法中除了複用的程式碼,其他的關鍵程式碼必須是抽象的,子類可以繼承實現。

優點

  • 它封裝了不變部分,擴充套件可變部分。它把認為是不變部分的演算法封裝到父類中實現,而把可變部分演算法由子類繼承實現,便於子類繼續擴充套件。
  • 它在父類中提取了公共的部分程式碼,便於程式碼複用。
  • 部分方法是由子類實現的,因此子類可以通過擴充套件方式增加相應的功能,符合開閉原則。

缺點

  • 對每個不同的實現都需要定義一個子類,這會導致類的個數增加,系統更加龐大,設計也更加抽象。
  • 父類中的抽象方法由子類實現,子類執行的結果會影響父類的結果,這導致一種反向的控制結構,它提高了程式碼閱讀的難度。

簡單演示

  • 比如遊戲的執行需要如下幾個步驟:上述的三個步驟可以是模板類的抽象方法,由具體的子類實現,比如足球遊戲。
    1. 初始化遊戲
    2. 開始遊戲
    3. 結束遊戲
  • 定義模板類,必須是一個抽象類,模板方法必須是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()
  • 抽象方法的定義便於子類去擴充套件,在保證演算法邏輯不變的情況下,子類能夠定製自己的實現。

具體子類

  • 事務管理器的模板類有很多的具體子類,如下圖:
  • 其中我們熟悉的有DataSourceTransactionManagerJtaTransactionManagerRabbitTransactionManager。具體承擔什麼樣的角色和責任不是本節的重點,不再細說。

總結

  • 模板模式是一個很重要,易擴充套件的模式,提高了程式碼複用性,在Spring中有著廣泛的應用,比如JDBCTemplate,AbstractPlatformTransactionManager,這些實現都用到了模板模式。
  • 如果覺得陳某的文章能夠對你有所幫助,有所啟發,關注分享一波,點個在看,謝謝支援!!!