设计模式七 模版模式

0、基本定义

定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。

重点不是选择,只能 重定义 该算法的某些特定的步骤。

这里场景模拟 JdbcTemplate

1、代码

public class JdbcTemplate {

    private DataSource dataSource;

    public JdbcTemplate(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    //方法封装
    private Connection getConnection() throws SQLException {
        return this.dataSource.getConnection();
    }

    private PreparedStatement createPreparedStatment(Connection con, String sql) throws SQLException {
        return con.prepareStatement(sql);
    }

    private ResultSet executeQuery(PreparedStatement stmt, Object[] values) throws SQLException {
        for (int i = 0; i < values.length; i++) {

            stmt.setObject(i, values[i]);
        }
        return stmt.executeQuery();
    }

    private void closeStatment(Statement stmt) throws SQLException {
        stmt.close();
    }

    private void closeResult(ResultSet rs) throws SQLException {
        rs.close();
    }

    private void closeConnection(Connection con) throws SQLException {
        con.close();
    }


    private List<?> parseResultSet(ResultSet rs, RowMapper rowMapper) throws Exception {
        List result = new ArrayList();
        int rowNum = 1;
        while (rs.next()) {

            result.add(rowMapper.mapRow(rs, rowNum++));
        }
        return result;
    }


    public List<?> executeQuery(String sql, RowMapper<?> rowMapper, Object[] values) throws Exception {

        //1、获取链接
        Connection connection = getConnection();//dataSource.getConnection();

        //2、创建语句集
        PreparedStatement pstmt = createPreparedStatment(connection, sql);//connection.prepareStatement(sql);

        //3、执行语句集、并且获得结果集
        ResultSet rs = executeQuery(pstmt, null);//pstmt.executeQuery();

        //4、解析语句集
        List<?> result = parseResultSet(rs, rowMapper);
//        List result = new ArrayList();
//        int rowNum = 1;
//        while (rs.next()) {
//
//            result.add(processResult(rs, rowNum));
//        }

        //5、关闭结果集
        this.closeStatment(pstmt);
        //6、关闭语句集
        this.closeResult(rs);
        //7、关闭链接
        this.closeConnection(connection);

        return result;
    }

//    public abstract Object processResult(ResultSet rs, int rowNum) throws SQLException;
}



public class MemberDao  {

    //不继承,为了 解耦
    private JdbcTemplate jdbcTemplate = new JdbcTemplate(null);

    public List query() throws Exception {
        String sql = "select * from t_member";
        return jdbcTemplate.executeQuery(sql, new RowMapper<Member>() {

            //用户 写的地方
            @Override
            public Member mapRow(ResultSet rs, int rowNum) throws Exception {
                Member member = new Member();
                member.setUsername(rs.getString("username"));
                member.setPassword(rs.getString("password"));
                member.setAge(rs.getInt("age"));
                return member;
            }
        }, null);
    }

//    @Override
//    public Object processResult(ResultSet rs, int rowNum) throws SQLException {
//        Member member = new Member();
//        member.setUsername(rs.getString("username"));
//        member.setPassword(rs.getString("password"));
//        member.setAge(rs.getInt("age"));
//        return member;
//    }
}


@Data
public class Member {

    private String username;
    private String password;
    private String nickname;

    private int age;
}

public interface RowMapper<T> {

    public T mapRow(ResultSet rs,int rowNum) throws Exception;
}

2、总结

优点:

》封装不变部分(父类),扩展可变部分(子类)

》提取公共部分代码,方便维护

策略模式 vs 模版模式

策略模式: 重在选择

模版模式: 侧重点不是选择,只能 参与 其中一部分的 自定义,个性化

====================================

模版模式,其实就是定义一整套固定流程,其中特定流程可以 个性化。

=====================================

参考资料:

咕泡学院

《大话设计模式》

《设计模式之蝉》

原文地址:https://www.cnblogs.com/idea-persistence/p/9539518.html