模版模式的优缺点:
-
优点
- 利用模板方法将相同处理逻辑的代码放到抽象父类中,可以提高代码的复用性
- 将不同的代码不同的子类中,通过对子类的扩展增加新的行为,提高代码的扩展性
-
缺点
- 每一个抽象类都需要一个子类来实现,这样导致类的个数增加,间接地增加了系统实现的复杂度
- 继承关系自身缺点,如果父类添加新的抽象方法,所有子类都要改一遍
下面用两个例子演示模版模式
- 1.下班回家吃饭,下班和吃饭不变,回家交通工具有多种变化(公交、地铁、骑行)
- 2.数据库jdb模版查询
1.下班回家吃饭示例代码
//抽象类,实现了不变的部分和执行顺序
public abstract class GoHome {
//模版方法,规则了执行顺序,以及子类要实现的逻辑
public void execute(){
offWork();
traffic();
eat();
}
protected final void offWork(){
System.out.println("下班...");
}
//抽象方法,由子类去实现
public abstract void traffic();
public void eat(){
System.out.println("吃饭");
}
}
//公交回家子类
public class TransitGoHome extends GoHome{
@Override
public void traffic() {
System.out.println("公交回家");
}
}
//地铁回家子类
public class MetroGoHome extends GoHome{
@Override
public void traffic() {
System.out.println("地铁回家");
}
}
//测试类
public class TestMain {
public static void main(String[] args) {
GoHome xiaoming = new TransitGoHome();
System.out.println("xiaoming...");
xiaoming.execute();
System.out.println("");
GoHome zhangsan = new MetroGoHome();
System.out.println("zhangsan...");
zhangsan.execute();
}
}
执行main方法
2.数据库jdb模版查询
//1.定义回调接口
public interface ResultSetHandler<T> {
public T handle(ResultSet rs);
}
//2.模版方法和使用
public class SimpleJdbcTemplate {
public static void main(String[] args) {
SimpleJdbcTemplate jdbcTemplate = new SimpleJdbcTemplate();
//用匿名内部类自行处理查询结果
List list = jdbcTemplate.query("select * from test", new ResultSetHandler<List>() {
@Override
public List handle(ResultSet rs) {
try {
//自定义处理查询结果
return convertList(rs);
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
});
}
/**
* 执行查询方法
* @param queryString
* @param resultSetHandler
* @param <T>
* @return
*/
public <T> T query(String queryString, ResultSetHandler<T> resultSetHandler){
try {
//获取connection和执行sql是不变的部分
Connection connection = getConnection();
//执行sql,获取结果集
ResultSet resultSet = getResultSet(queryString, connection);
//把变化的部分用回调的方式让客户端自行处理
return resultSetHandler.handle(resultSet);
}catch (SQLException e){
e.printStackTrace();
}
return null;
}
/**
* 获取数据库connection
* @return
* @throws SQLException
*/
private static Connection getConnection() throws SQLException {
String url = "";
String username = "";
String password = "";
final Connection connection = DriverManager.getConnection(url, username, password);
return connection;
}
/**
* 执行sql,获取结果集
* @param queryString
* @param connection
* @return
* @throws SQLException
*/
private static ResultSet getResultSet(String queryString, Connection connection) throws SQLException {
PreparedStatement statement = connection.prepareStatement(queryString);
ResultSet resultSet = statement.executeQuery();
return resultSet;
}
/**
* 将ResultSet结果集转换为List
* @param rs
* @return
* @throws SQLException
*/
private static List convertList(ResultSet rs) throws SQLException{
List list = new ArrayList();
ResultSetMetaData md = rs.getMetaData();//获取键名
int columnCount = md.getColumnCount();//获取行的数量
while (rs.next()) {
Map rowData = new HashMap();//声明Map
for (int i = 1; i <= columnCount; i++) {
rowData.put(md.getColumnName(i), rs.getObject(i));//获取键名及值
}
//可多接受一个Class<T> clazz参数,将map转为指定的clazz对象
list.add(rowData);
}
return list;
}
}