上一节说到外观模式:https://blog.csdn.net/zhanglei082319/article/details/88829545
外观模式:将一个功能关联的多个服务模块,组合成一个大模块,供调用者使用。
今天说一种新的设计模式:模板方法模式
模板方法模式: java多态使用的一种体现,一个具体业务功能的父类实现中有些不能实现的功能,交给子类来实现,而且每种子类实现的方式都不相同,并且不会影响父类的整体业务实现。
程序中模板方法模式的使用场景不要太多,比如:网购支付,数据源或者持久层调用,消息发送方式,策略选择,算法选择,树形节点路由处理等等
网购支付:可以分为多个子类,如支付宝支付,微信支付,银行账号支付,通联支付等等。
数据源持久层:一般项目为了可以支持多个持久层框架,如可以支持mybatis,spring.jdbcTemplate,hibernate,jdbc等等。
消息发送方式:也可以分为多个子类,如短信消息,桌面提醒,邮件提醒等等。
下面我们就支持多个持久层来编写一个简单的木模板方法模式:
1、新建一个查询抽象类
/**
* 数据查询服务
*/
public abstract class Db {
/**
* 抽象查询 供子类来实现
*
* @param sql 查询语句
* @param args 查询参数
* @param clazz 数据类型
* @param <T> 返回类型
* @return 返回值
*/
public abstract <T>List<T> query(String sql,Object[] args,Class<T> clazz);
/**
* 查询user
*
* @param filter 查询参数
* @return 用户集合
*/
public List<User> queryUser(QueryFilter filter){
Object[] args = new Object[]{filter.getSystem(),filter.getVersion()};
String sql = "select * from user where system=? and version=? ";
return query(sql,args,User.class);
}
}
2、使用jdbc方式来实现查询
/**
* 使用jdbc实现 这里演示就不用连接池了
*
* @author zhanglei
*/
public class JdbcDb extends Db {
/**
* 数据源
*/
private DataSource dataSource;
/**
* apache dbutils
*/
private final QueryRunner queryRunner = new QueryRunner(true);
public JdbcDb(DataSource source){
this.dataSource = source;
}
/**
* 具体子类实现
*/
@Override
public <T> List<T> query(String sql, Object[] args,Class<T> clazz) {
Connection conn = getConnection();
try {
return this.queryRunner.query(conn,sql,new ResultHandler<>(clazz),args);
} catch (SQLException e) {
throw new RuntimeException(e.getMessage());
}
}
public synchronized Connection getConnection() {
try {
return dataSource.getConnection();
} catch (SQLException e) {
throw new RuntimeException(e.getMessage());
}
}
}
3、使用mybatis方式实现查询,这里mybatis可以直接使用jdbc的实现。需要重写getConnection
/**
* mybatis方式实现
*/
public class MybatisDb extends JdbcDb{
/**
* mybatis的sqlSessionFactory
*/
private SqlSessionFactory sqlSessionFactory;
public MybatisDb(SqlSessionFactory sqlSessionFactory){
this.sqlSessionFactory = sqlSessionFactory;
}
@Override
public synchronized Connection getConnection() {
return sqlSessionFactory.openSession().getConnection();
}
}
4、spring jdbcTemplate实现:
/**
* spring实现
*/
public class SpringDb extends Db {
/**
* jdbcTemplate
*/
private JdbcTemplate jdbcTemplate;
public SpringDb(JdbcTemplate jdbcTemplate){
this.jdbcTemplate = jdbcTemplate;
}
@Override
public <T> List<T> query(String sql, Object[] args, Class<T> clazz) {
return this.jdbcTemplate.query(sql,new BeanPropertyRowMapper<>(clazz),args);
}
}
这样查询用户的持久层接口,就可以支持jdbc ,mybatis ,spring 如果需要继续支持其他持久层框架,只需要添加一个子类即可。