デザインパターン:テンプレートパターン

テンプレート モードの長所と短所:

  • アドバンテージ

    • テンプレート メソッドを使用して、同じ処理ロジックのコードを抽象親クラスに配置すると、コードの再利用性が向上します。
    • 異なるコードを異なるサブクラスに配置し、サブクラスを拡張して新しい動作を追加してコードのスケーラビリティを向上させます。
  • 欠点がある

    • 各抽象クラスは実装するサブクラスを必要とするため、クラスの数が増加し、間接的にシステム実装の複雑さが増加します。
    • 継承関係には独自の欠点があり、親クラスが新しい抽象メソッドを追加すると、すべてのサブクラスでそれを変更する必要があります。

以下の 2 つの例を使用してテンプレート モードを説明します。

  • 1. 仕事を終えて帰宅したら食事をする 仕事を終えてから食事する時間は変わりませんが、帰宅の交通手段(バス、地下鉄、自転車)は大きく変わります。
  • 2. データベース JDB テンプレート クエリ
1. 仕事帰りに食事するサンプルコード
//抽象类,实现了不变的部分和执行顺序
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();
    }
}

mainメソッドを実行する
ここに画像の説明を挿入します


2. データベース JDB テンプレート クエリ
//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;
    }
}

おすすめ

転載: blog.csdn.net/zhuyu19911016520/article/details/127487544