設(shè)計(jì)模式-模板方法模式

模板方法(Template Method)模式的定義:定義一個(gè)操作中的算法骨架,而將算法的一些步驟延遲到子類中,使得子類可以不改變?cè)撍惴ńY(jié)構(gòu)的情況下重定義該算法的某些特定步驟。它是一種類行為型模式.
其優(yōu)點(diǎn)有:

  • 封裝了不變部分,擴(kuò)展可變部分。
  • 在父類中提取了公共的部分代碼,便于代碼復(fù)用。
  • 部分方法是由子類實(shí)現(xiàn)的,因此子類可以通過擴(kuò)展方式增加相應(yīng)的功能,符合開閉原則。

模式結(jié)構(gòu)

模板方法模式包含以下主要角色:

  • 抽象類:負(fù)責(zé)給出一個(gè)算法的輪廓和骨架。它由一個(gè)模板方法和若干個(gè)基本方法構(gòu)成。
  • 具體子類:實(shí)現(xiàn)抽象類中所定義的抽象方法和鉤子方法,它們是一個(gè)頂級(jí)邏輯的一個(gè)組成步驟。

源碼導(dǎo)讀

模板方法模式一般以“XXXtemplate”這種方式來命名,像我們所熟知的JdbcTemplate 就是采用模板方法模式設(shè)計(jì)的。
我們先看不使用JdbcTemplate 是怎么查詢的:

        try{
            Class.forName("com.mysql.jdbc.Driver");
            connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "1234");
            String sql = "select nickname,comment,age from users";
            statement = connection.createStatement();
            ResultSet resultSet = statement.executeQuery(sql);
            List<Users> usersList = new ArrayList<>();
            while (resultSet.next()) {
                Users users = new Users();
                users.setNickname(resultSet.getString(1));
                users.setComment(resultSet.getString(2));
                users.setAge(resultSet.getInt(3));
                usersList.add(users);
            }
            return usersList;
        } catch (Exception e) {
            e.printStackTrace();
       
        } finally {
            try {
                if (null != statement) {
                    statement.close();
                }
                if (null != connection) {
                    connection.close();
                }
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
        return null;

我們執(zhí)行一次sql總是這樣一個(gè)流程:加載驅(qū)動(dòng)-》獲取連接-》執(zhí)行sql-》創(chuàng)建一個(gè)Statement-》獲得返回值。對(duì)于這種固定步驟的功能,我們就可以考慮用模板方法模式來實(shí)現(xiàn)了。

JDBCTemplate繼承了基類JdbcAccessor和接口類JdbcOperation。在基類JdbcAccessor的設(shè)計(jì)中,對(duì)DataSource數(shù)據(jù)源進(jìn)行管理和配置。在JdbcOperation接口中,定義了通過Jdbc操作數(shù)據(jù)庫的基本操作方法,而JdbcTemplate提供這些接口方法的實(shí)現(xiàn),比如execute方法、query方法、update方法等。
jdbcTemplate的核心方法是execute

public <T> T execute(StatementCallback<T> action) throws DataAccessException {
        Assert.notNull(action, "Callback object must not be null");

        Connection con = DataSourceUtils.getConnection(getDataSource());
        Statement stmt = null;
        try {
            Connection conToUse = con;
            if (this.nativeJdbcExtractor != null &&
                    this.nativeJdbcExtractor.isNativeConnectionNecessaryForNativeStatements()) {
                conToUse = this.nativeJdbcExtractor.getNativeConnection(con);
            }
            stmt = conToUse.createStatement();
            applyStatementSettings(stmt);
            Statement stmtToUse = stmt;
            if (this.nativeJdbcExtractor != null) {
                stmtToUse = this.nativeJdbcExtractor.getNativeStatement(stmt);
            }
            T result = action.doInStatement(stmtToUse); // 回調(diào)
            handleWarnings(stmt);
            return result;
        }
        catch (SQLException ex) {
            JdbcUtils.closeStatement(stmt);
            stmt = null;
            DataSourceUtils.releaseConnection(con, getDataSource());
            con = null;
            throw getExceptionTranslator().translate("StatementCallback", getSql(action), ex);
        }
        finally {
            JdbcUtils.closeStatement(stmt);
            DataSourceUtils.releaseConnection(con, getDataSource());
        }
    }

在模板方法模式中,類的方法被劃分為這幾類:模板方法(定義了算法的骨架,按某種順序調(diào)用其包含的基本方法),基本方法(包括抽象方法,具體方法,鉤子方法)

這個(gè)execute 便是它的模板方法了。而getDataSource()便是在父類中已經(jīng)實(shí)現(xiàn)的基本方法。

點(diǎn)擊關(guān)注我的博客

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容