java23种设计模式之模板方法模式

上一节说到外观模式: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 如果需要继续支持其他持久层框架,只需要添加一个子类即可。

猜你喜欢

转载自blog.csdn.net/zhanglei082319/article/details/88906694