Spring中的Callback模式與Template模式合用,隨處可見。Template method被廣泛的使用,像Servlet就是使用這個(gè)模式。Template mothod模式雖然能簡化很多重復(fù)的代碼,但這種模式的也有不少限制。Template mothod將一個(gè)功能的實(shí)現(xiàn)分成許多小的步驟,在父類中定義了這些步驟的順序,讓子類來具體實(shí)現(xiàn)每一個(gè)小的步驟。這些小的步驟是protected,以防止用戶不正確的使用這些小的步驟而產(chǎn)生異常。這樣就產(chǎn)生了一個(gè)限制,那就是你需要繼承Template然后重新實(shí)現(xiàn)具體的小步驟。如果這個(gè)Template有許多方法,就像JdbcTemplate,如果你每次繼承這個(gè)龐大的類,然后只是重寫某個(gè)小步驟中來訂制你自己的功能,就會顯得非常笨重,更何況數(shù)據(jù)庫操作使用的如此頻繁,難道你每進(jìn)行一個(gè)操作就通過繼承訂制一個(gè),顯然不可能這么做。
Spring使用Callback模式與之配合,達(dá)到了去掉重復(fù)代碼的效果,同時(shí)增加了很大的靈活性,你只需要實(shí)現(xiàn)某些CallBack就可輕松訂制出Template。
那么什么時(shí)候才是Callback模式與Template模式結(jié)合的最佳時(shí)機(jī)呢。顯然如果每個(gè)具體的步驟都需要真正去具體實(shí)現(xiàn)而不是簡單的改變參數(shù)或設(shè)置某個(gè)對象就ok的話,使用Callback很難去訂制,因?yàn)槟憧赡苄枰獋鬟f多個(gè)Callback作為參數(shù),并讓用戶去實(shí)現(xiàn),是用Java的內(nèi)部類本來就是一個(gè)比較丑陋的語法,更何況參數(shù)是多個(gè)。這相當(dāng)于你把每個(gè)小步驟封裝成為接口,然后分別繼承之然后實(shí)現(xiàn)。顯然沒有達(dá)到方便靈活的效果,這時(shí)候直接使用Template method模式就比結(jié)合Callback要好。而如果用戶只需要定制一個(gè)方法能就達(dá)到用戶的要求,或者更簡單,只是設(shè)置不同的參數(shù),那么使用Callback就具有很好的靈活性。
Template例子
Servlet
Callback 例子
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
jdbcTemplate
.update(
"UPDATE user SET age = ? WHERE id = ?",
new PreparedStatementSetter() {
public void setValues(PreparedStatement ps)
throws SQLException {
ps.setInt(1, 18);
ps.setString(2, "erica");
}
}
);