模板方法模式屬於行爲型模式,它定義一個操做中的算法的骨架,而將一些步驟推遲到子類當中實現。父類抽取並實現的是公共方法,對於可變方法,父類作的只是定義了可變行爲的接口,具體實現留給子類去完成,實現對代碼的重複利用。java
這裏的templateMethod方法就是公共方法,是全部子類所擁有的公共行爲;abstractMethod方法就是可變的行爲,是每一個子類獨特行爲,這種行爲只能由它們來實現。算法
拿<<大話設計模式>>上的例子來講,學生是共用一套試卷,只是學生各自的答案是不一樣的;所以,試題題目是模板方法是不變的,而試題答案對於每一個學生是可變的spring
/** * */ public abstract class AbstractTemplate { private String name; public AbstractTemplate(String name){ this.name = name; } public void question(){ System.out.print(name + ":1 + 1 = "); System.out.print(answer()); System.out.println(); } public abstract int answer(); } public class StudentATemplate extends AbstractTemplate{ @Override public int answer() { return 2; } public StudentATemplate(String name) { super(name); } } public class StudentBTemplate extends AbstractTemplate{ public StudentBTemplate(String name) { super(name); } @Override public int answer() { return 3; } }
測試代碼sql
@Test public void templatePatternTest(){ AbstractTemplate aTempate = new StudentATemplate("小紅"); AbstractTemplate bTempate = new StudentBTemplate("小明"); aTempate.question(); bTempate.question(); }
輸出結果以下數據庫
spring中的JdbcTemplate類就運用了模板方法,java在執行數據庫操做時的步驟無非以下幾步:設計模式
在這裏只是簡單,介紹一下,所以針對PreparedStatement,最大的可變之處就是5,6這個部分,所以JdbcTemplate將1,2,3,4,7製做成模板(主要在execute方法中),而對於5,6它經過匿名內部類的形式來實現(也就是說對於update、query等等操做,都對5,6經過匿名內部類有不一樣的實現,匿名內部類實現的都是callback接口,*callback都是額外定義的接口)ide
@Override public <T> T query(final String sql, final ResultSetExtractor<T> rse) throws DataAccessException { Assert.notNull(sql, "SQL must not be null"); Assert.notNull(rse, "ResultSetExtractor must not be null"); if (logger.isDebugEnabled()) { logger.debug("Executing SQL query [" + sql + "]"); } //匿名內部類 class QueryStatementCallback implements StatementCallback<T>, SqlProvider { @Override public T doInStatement(Statement stmt) throws SQLException { ResultSet rs = null; try { rs = stmt.executeQuery(sql); ResultSet rsToUse = rs; if (nativeJdbcExtractor != null) { rsToUse = nativeJdbcExtractor.getNativeResultSet(rs); } return rse.extractData(rsToUse); } finally { JdbcUtils.closeResultSet(rs); } } @Override public String getSql() { return sql; } } //真正執行的方法 return execute(new QueryStatementCallback()); }
這裏只貼出了其中一個query方法,其餘的」套路」都跟它差很少,若是感興趣的話本身能夠深究一下JdbcTemplate源碼測試
抽出不變行爲,對代碼的重複利用;要擴展的話,只需添加子類this
按照咱們的設計習慣,抽象類負責聲明最抽象、最通常的事情屬性和方法,實現類完成具體的事物屬性和debug
方法。可是模板方法模式卻顛倒了,抽象類定義了部分抽象方法,由子類實現,子類執行結果影響了父類的
結果,也就是子類對父類產生了影響,這在複雜的項目中,會帶來代碼閱讀的難度,並且也會讓新手產生不
適感,由於引入了一個抽象類,若是具體實現過多的話,須要用戶或開發人員須要花更多的時間去理清類之
間的關係