1.使用背景
模板方法模式是通过将不变的行为移至超类并去除子类中的重复代码来提取其优点。 它提供了一个良好的代码重用平台。 当不可变和可变方法混合在子类中时,
不变的方法会在子类中出现多次,所以如果一个方法需要修改的话,就需要修改很多次,虽然这个问题在设计之初就应该考虑到。 这时候,模板方法模式就发挥了作用。
通过模板方法模式将这些重复的方法移到一个地方,可以帮助子类摆脱重复不变性的纠缠。
2、以示例中的模板模式为例,说明其优点;
( sc) 公共方法,封装了可重用的代码;
参数是一个接口,接口方法是(),这个方法是实现不同操作的方法; 也就是说,这里提出了不同的实现;
public L execute(StatementCallback action)
{
try{
1. 加载驱动
2. 建立连接
3. 获取Statement stmt
@Override
public T query(final String sql, final ResultSetExtractor 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, 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());
}
当调用查询方法时,该方法将被执行。 该方法是模板方法,并且由于该方法内部调用了传入的接口的方法,但是该方法可以通过在查询方法中传入匿名内部类来自定义使用; 完全符合模板模式使用;
1.使用hook方法来控制模板的不同行为
下面以汽车为例来说明hook方法的使用:
public abstract class HummerModel {
protected abstract void start(); //发动
protected abstract void stop(); //停止
protected abstract void alarm(); //鸣笛
protected abstract void engineBoom(); //轰鸣
final public void run() { //车总归要跑
this.start();
this.engineBoom();
if(this.isAlarm()) {//想让它叫就叫,不想就不叫
this.alarm();
}
this.stop();
}
protected boolean isAlarm() { //我们加了一个判断方法,默认返回true
return true;
}
}
public class HummerH1 extends HummerModel {
private boolean alarmFlag = true; //判断标记
@Override
public void start() {
System.out.println("H1发动……");
}
@Override
public void stop() {
System.out.println("H1停止……");
}
@Override
public void alarm() {
System.out.println("H1鸣笛……");
}
@Override
public void engineBoom() {
System.out.println("H1轰鸣……");
}
@Override
protected boolean isAlarm() { //覆写isAlarm方法,返回判断标记
return this.alarmFlag;
}
public void setAlarm(boolean isAlarm) { //设置判断标记
this.alarmFlag = isAlarm;
}
}
这段代码中,我们在模板方法中增加了判断标记,然后子类对外提供一个public接口setAlarm来让外界设置这个判断标记,这个判断标记就像是开关一样,想让它ture和false都行。
这个isAlarm方法俗称钩子方法。有了钩子方法的模板方法模式才算完美,使得我们的控制行为更加的主动,更加的灵活。