Template 模式指的就是在父类中定义一个操作中算法的骨架或者说操作顺序,而将一些步骤
的具体实现延迟到子类中。这个模式可能是目前最简单的模式了,这里以一个示例做说明。
假如要设计一个事务处理类,这个类要处理事务,这个是确定的,但是要处理哪些事务却是不知道的,所以可以在父类中编写事务处理的骨架代码,指明事务处理的操作顺序,而具体的事务则可以延迟的子类中去实现。具体实现步骤如下:
(1)在父类Transaction 中编写事务处理的骨架代码,指明事务处理的操作顺序,
Transaction.java 的示例代码如下:
//******* Transaction.java**************
public abstract class Transaction{
//事务处理的骨架代码,指明事务处理的操作顺序
public Object execute() throws TransactionException {
this.transactionManager.getTransaction(this);
Object result = null;
try {
result =doInTransaction();
} catch (Error err) {
// Transactional code threw error -> rollback
this.transactionManager.rollback(this);
throw err;
}
this.transactionManager.commit(this);
return result;
}
//负责传入具体的事务
Public abstract Object doInTransaction ();
}
(2)在子类 SubTransaction中编写具体要进行事务处理的代码,SubTransaction.java的示例
代码如下:
//******* SubTransaction.java**************
public class SubTransaction extends Transaction {
//负责传入具体的事务
Public Object doInTransaction () {
//具体对数据库进行新增、修改、删除的代码
……
}
}
(3)这样当有具体的业务逻辑调用 SubTransaction. Execute()方法时,就会进行事务处理。
注意:在子类中,是必须要延迟到子类进行的才在子类中做,否则没有必要在子类中做。
而接口就无法像抽象类似的这样做,因为接口并不能具体实现任何操作。
7.3.2 回顾事务处理中TransactionTemplate的实现方式
然而 Spring提供了另外一种实现 Template模式的方法,利用接口回调函数,也是很有意思
的,来看一下前面讲过的 Spring的事务处理方式:
(1)TransactionTemplate的示例代码如下:
//******* TransactionTemplate.java**************
public class TransactionTemplate extends DefaultTransactionDefinition implements
InitializingBean{
……
//进行事务处理的骨架代码,指明了事务处理的顺序
public Object execute(TransactionCallback action) throws TransactionException {
TransactionStatus status = this.transactionManager.getTransaction(this);
Object result = null;
try {
result =action.doInTransaction(status);
}
catch (RuntimeException ex) {
// Transactional code threw application exception -> rollback
rollbackOnException(status, ex);
throw ex;
}
catch (Error err) {
// Transactional code threw error -> rollback
rollbackOnException(status, err);
throw err;
}
this.transactionManager.commit(status);
return result;
}
//事务处理回调时调用
private void rollbackOnException(TransactionStatus status, Throwable ex) throws
TransactionException {
try {
this.transactionManager.rollback(status);
}
}
}
catch (RuntimeException ex2) {
throw ex2;
}
catch (Error err) {
throw err;
}
代码说明:
这里 TransactionTemplate没有使用抽象类,在它的 execute()方法里定义的事务理的骨架代码。
但是 execute()方法的 TransactionCallback参数却是个接口,在这个接口中定义了
doInTransaction()方法。
(2)接着来看一下 TransactionCallback的实现,TransactionCallback.java的示例代码如下:
//******* TransactionCallback.java**************
public interface TransactionCallback {
Object doInTransaction(TransactionStatus status);
}
(3)只要实现 TransactionCallback接口,并在 doInTransaction()方法里编写具体要进行事
务处理的代码就可以了。简单的示例代码如下:
//******* HelloDAO.java**************
package com.gc.action;
import javax.sql.DataSource;
import org.springframework.jdbc.core.*;
import org.springframework.transaction.*;
import org.springframework.transaction.support.*;
import org.springframework.dao.*;
public class HelloDAO {
private DataSource dataSource;
private PlatformTransactionManager transactionManager;
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
public void setTransactionManager(PlatformTransactionManager transactionManager) {
this.transactionManager = transactionManager;
}
public int create(String msg) {
TransactionTemplate transactionTemplate= new TransactionTemplate(transactionManager);
Object result = transactionTemplate.execute(
new TransactionCallback() {
public Object doInTransaction(TransactionStatus status) {
// 执行新增的操作,向数据库新增一笔记录
…….
// 返回值是resultObject
return resultObject;
});
}
}
代码说明:
在 HelloDAO的 create()方法里,对 TransactionCallback接口的doInTransaction()方法进行了实现。
多多钻研 Spring 的源代码会对开发人员的编程能力有很大的提高,接下来将要讲解的
JdbcTemplate 也同样用类似的方式实现了 Template模式。