经典模板方法定义:

父类定义了骨架(调用哪些方法及顺序),某些特定方法由子类实现。

最大的好处:代码复用,减少重复代码。除了子类要实现的特定方法,其他方法及方法调用顺序都在父类中预先写好了。

所以父类模板方法中有两类方法:

共同的方法: 所有子类都会用到的代码

不同的方法: 子类要覆盖的方法,分为两种:

抽象方法:父类中的是抽象方法,子类必须覆盖

钩子方法:父类中是一个空方法,子类继承了默认也是空的

注:为什么叫钩子,子类可以通过这个钩子(方法),控制父类,因为这个钩子实际是父类的方法(空方法)!

Spring模板方法模式实质:

是模板方法模式和回调模式的结合,是Template Method不需要继承的另一种实现方式。Spring几乎所有的外接扩展都采用这种模式。

具体实现:

JDBC的抽象和对Hibernate的集成,都采用了一种理念或者处理方式,那就是模板方法模式与相应的Callback接口相结合。

采用模板方法模式是为了以一种统一而集中的方式来处理资源的获取和释放,以JdbcTempalte为例:

public abstract class JdbcTemplate { public final Object execute(String sql){ Connection con=null; Statement stmt=null; try{ con=getConnection(); stmt=con.createStatement(); Object retValue=executeWithStatement(stmt,sql); return retValue; }catch(SQLException e){ ... }finally{ closeStatement(stmt); releaseConnection(con); } } protected abstract Object executeWithStatement(Statement stmt, String sql);}
引入回调原因:
JdbcTemplate是抽象类,不能够独立使用,我们每次进行数据访问的时候都要给出一个相应的子类实现,这样肯定不方便,所以就引入了回调。
回调代码
public interface StatementCallback{ Object doWithStatement(Statement stmt);}
利用回调方法重写JdbcTemplate方法
public class JdbcTemplate{ public final Object execute(StatementCallback callback){ Connection con=null; Statement stmt=null; try{ con=getConnection(); stmt=con.createStatement(); Object retValue=callback.doWithStatement(stmt); return retValue; }catch(SQLException e){ ... }finally{ closeStatement(stmt); releaseConnection(con); } } ...//其它方法定义}
Jdbc使用方法如下:
JdbcTemplate jdbcTemplate=...; final String sql=...; StatementCallback callback=new StatementCallback(){ public Object=doWithStatement(Statement stmt){ return ...; }}jdbcTemplate.execute(callback);

为什么JdbcTemplate没有使用继承?

因为这个类的方法太多,但是我们还是想用到JdbcTemplate已有的稳定的、公用的数据库连接,那么我们怎么办呢?

我们可以把变化的东西抽出来作为一个参数传入JdbcTemplate的方法中。但是变化的东西是一段代码,而且这段代码会用到JdbcTemplate中的变量。怎么办?

那我们就用回调对象吧。在这个回调对象中定义一个操纵JdbcTemplate中变量的方法,我们去实现这个方法,就把变化的东西集中到这里了。然后我们再传入这个回调对象到JdbcTemplate,从而完成了调用。