Design pattern: Template pattern

Advantages and disadvantages of template mode:

  • advantage

    • Using the template method to put the code with the same processing logic into the abstract parent class can improve the reusability of the code.
    • Put different codes into different subclasses and add new behaviors by extending the subclasses to improve the scalability of the code.
  • shortcoming

    • Each abstract class requires a subclass to implement, which increases the number of classes and indirectly increases the complexity of system implementation.
    • The inheritance relationship has its own shortcomings. If the parent class adds a new abstract method, all subclasses will have to change it.

The following two examples are used to demonstrate the template mode

  • 1. Eat when you go home from get off work. The time after get off work and eating remain the same. There are many changes in the means of transportation home (bus, subway, bicycle).
  • 2. Database jdb template query
1. Sample code for eating when you get home from get off work
//抽象类,实现了不变的部分和执行顺序
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();
    }
}

Execute main method
Insert image description here


2. Database jdb template query
//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;
    }
}

Guess you like

Origin blog.csdn.net/zhuyu19911016520/article/details/127487544
Recommended