模板模式

学习目的

》通过学习模板模式,能够在实际业务中完成标准化业务场景

在某些业务场景中,有时候实现一个业务。可能有一些步骤来实现,而每个步骤中会出现不同的场景。此时我们可以那些不变的步骤提取到父类中实现。而那些可变的内容则进行抽象,并通过不同的子类进行完成。

在这里我们利用模板模式完成jdbc的一个标准化业务场景流程

通过一个jdbc操作来实现一个

  1. 加载驱动类
  2. 获取连接
  3. 获取预处理命令
  4. 执行sql语句,获取结果集
  5. 解析结果集
  6. 关闭连接
            //加载驱动
            Class.forName("com.mysql.jdbc.Driver");
            //获取连接
            Connection conn = DriverManager.getConnection("jdbc:mysql://192.168.1.152:3306/demo","root","");
            //获取预处理命令
            PreparedStatement ps = conn.prepareStatement("select * from mms_menu");
            //获取结果集
            ResultSet resultSet = ps.executeQuery();

            //解析结果集
            while (resultSet.next()){
               Menu menu = new Menu();
               menu.setCreatedTime(resultSet.getDate("created_time"));
               menu.setId(resultSet.getInt("id"));
               menu.setName(resultSet.getString("name"));
               menu.setUrl(resultSet.getString("url"));
                System.out.println(menu);
            }
            //关闭连接
            resultSet.close();
            ps.close();
            conn.close();

这是一个很普遍的sql查询,在我们实际的开发中肯定是不会每个命令都这么写一遍的。下面我们通过模板模式来优化这些代码。

对连接管理的工具类

/**
 * @Description:
 * @Author: gege
 * @CreateDate: 2019/3/26 10:30
 */
public class JdbcUtils {

    static{
        try {
            Class.forName("com.mysql.jdbc.Driver");
        }catch (Exception e){
            System.out.println("找不到驱动类");
        }
    }
    private JdbcUtils (){}

    private static Connection conn;
    private static PreparedStatement prepareStatement;

    //这些参数我们后期往往通过配置文件来配置
    private final static String DRIVER_NAME="com.mysql.jdbc.Driver";
    private final static String URL="jdbc:mysql://192.168.1.152:3306/demo";
    private final static String USER_NAME="root";
    private final static String PASS_WORD="";

    //获取连接
    public static Connection getConnection() throws SQLException {
        conn =   DriverManager.getConnection("jdbc:mysql://192.168.1.152:3306/demo","root","");
        return conn;
    }


    public static void close(ResultSet rs ,PreparedStatement ps ,Connection conn) throws SQLException{
            rs.close();
            ps.close();
            conn.close();
    }
}

通过模板方法将具体的操作实现在父类上,将抽象的步骤定义成一个接口。并有具体的类去实现

/**
     * 查询
     * @param mapper 要映射结果集实体的实现类
     * @param sql sql查询语句
     * @param params sql查询参数
     * @return sql查询返回的集合
     * @throws SQLException
     */
    public List<T> executeQuery(IRowMapper<T> mapper,String sql ,Object...params)throws SQLException {
        Connection conn =JdbcUtils.getConnection();
        PreparedStatement ps = conn.prepareStatement(sql);
        if(params!=null)
        for (int i=0;i<params.length;i++)
            ps.setObject(i+1,params[i]);
        ResultSet resultSet = ps.executeQuery();
        List<T> queryList = new ArrayList<T>();
        while (resultSet.next()){
            //此处的逻辑是根据不同的实体集来实现的不同业务逻辑,是可变的,我们将其抽象出来。
            //等待子类去完成此业务
            T entity = mapper.parseEntity(resultSet);
            queryList.add(entity);
        }
        JdbcUtils.close(resultSet,ps,conn);
        return queryList;
    }

此处是我们定义的接口

public interface IRowMapper<T> {
    T parseEntity(ResultSet rs)throws SQLException;
}

下面是我们具体的实现类

public class MenuDao extends JdbcTemplate<Menu>{

    public List<Menu> queryByNames(String[] names) throws SQLException {
        StringBuffer sql =new StringBuffer("select * from mms_menu where name in (");
        for (int i=0;i<names.length;i++) {
            sql.append("?");
            if(i==names.length-1) sql.append(")");
            else sql.append(",");
        }
        System.out.println(sql.toString());
       return  super.executeQuery(new IRowMapper<Menu>() {
            public Menu parseEntity(ResultSet resultSet) throws  SQLException{
                Menu menu = new Menu();
                menu.setCreatedTime(resultSet.getDate("created_time"));
                menu.setId(resultSet.getInt("id"));
                menu.setName(resultSet.getString("name"));
                menu.setUrl(resultSet.getString("url"));
                return menu;
            }
        },sql.toString(),names);
    }
}

测试

  String[] names = {"${pageGenerate}","短信平台","接口管理"};
        MenuDao menuDao = new MenuDao();
       List<Menu> menus =  menuDao.queryByNames(names);
        for (Menu menu:menus) {
            System.out.println(menu);
        }

小结:

模板模式的优缺点

优点: 1、利用模板方法将相同处理逻辑的代码放到抽象父类中,可以提高代码的复用性。

2、将不同的代码不同的子类中,通过对子类的扩展增加新的行为,提高代码的扩展性。

3、把不变的行为写在父类上,去除子类的重复代码,提供了一个很好的代码复用平台, 符合开闭原则。

缺点:

1、类数目的增加,每一个抽象类都需要一个子类来实现,这样导致类的个数增加。

2、类数量的增加,间接地增加了系统实现的复杂度。

3、继承关系自身缺点,如果父类添加新的抽象方法,所有子类都要改一遍。 模板方法模式比较简单,相信小伙伴们肯定能学会,也肯定能理解好!只要勤加练习, 多结合业务场景思考问题,就能够把模板方法模式运用好。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值