在物件導向系統的分析與設計過程中經常會遇到這樣一種情況:對於某一個業務邏輯(演算法實現)在不同的物件中有不同的細節實現,但是邏輯(演算法)的框架(或通用的應用演算法)是相同的。Template Method提供了這種情況的一個實現框架。
Template Method模式是採用繼承的方式實現這一點:將邏輯(演算法)框架放在抽象基類中,並定義好細節的介面,子類中實現細節。
Strategy模式解決的是和Template Method模式類似的問題,但是Strategy模式是將邏輯(演算法)封裝到一個類中,並採取組合(委託)的方式解決這個問題。
解決這個問題可以採取兩種模式來解決,一是Template模式,二是Strategy模式。本文給出的是Template Method模式。一個通用的Template Method模式的結構圖為:
Template Method模式實際上就是利用物件導向中多型的概念實現演算法實現細節和高層介面的鬆耦合。可以看到Template Method模式採取的是繼承方式實現這一點的,由於繼承是一種強約束性的條件,因此也給Template Method模式帶來一些許多不方便的地方。
下面以程式碼的形式實現模板方法的應用,具體用途在註釋中已經很明確。
package designpattern_templatemethod; public class TemplateMethodTest { public static void main(String[] args) { CommonDAO dao = new TemplateMethodTest().new CommonDAOImpl(); /* * 直接傳入要執行的SQl語句執行查詢,即可獲得擁有事務的功能,同時省去了大部分訪問資料庫通用的方法,這些方法都在模板方法中 預先定義好了 */ dao.executeSQL("inserte into user values(1,'franson','male')"); } abstract class CommonDAO { final public void executeSQL(String sql) { try { System.out.println("獲取資料庫連線..."); System.out.println("開啟連線..."); System.out.println("開啟事務..."); executeDetail(sql);// 呼叫執行SQL語句的具體方法,該方法在子類中覆寫 System.out.println("提交事務..."); } catch (Exception e) { System.out.println("發生異常,回滾事務..."); } finally { System.out.println("關閉連線,釋放資源..."); } } protected abstract void executeDetail(String sql); } class CommonDAOImpl extends CommonDAO { @Override protected void executeDetail(String sql) { System.out.println(sql); } } }
Template Method模式的實現關鍵是將通用演算法(邏輯)封裝起來,而將演算法細節讓子類實現(多型)。唯一注意的是我們將原語操作(細節演算法)定義為受保護(Protected)成員,對外部只提供模板方法供呼叫。
Template模式是很簡單模式,但是也應用很廣的模式。Template Method是採用繼承的方式實現演算法的異構,其關鍵點就是將通用演算法封裝在抽象基類中,並將不同的演算法細節放到子類中實現。
Template Method模式獲得一種反向控制結構效果,這也是物件導向系統的分析和設計中一個原則----DIP(依賴倒置:Dependency Inversion Principles)。其含義就是父類呼叫子類的操作(高層模組呼叫低層模組的操作),低層模組實現高層模組宣告的介面。這樣控制權在父類(高層模組),低層模組反而要依賴高層模組。