一天一個設計模式——模板方法(Template Method)模式

1、模式說明java

  現實世界中的模板是用於將事物的結構規律予以固定化、標準化的成果,它體現告終構形式的標準化。例如鏤空文字印刷的模板,經過某個模板印刷出來的文字字體大小都是如出一轍,可是具體使用什麼材質的顏料,什麼顏色的顏料來印刷文字,取決於具體實際業務場景的須要。因而可知,模板制定了某些固定的條條框框,以及事物的處理標準流程,可是並無說明如何去作,具體如何作,取決於使用模板的人。mysql

  在程序設計領域,模板是具備一系列抽象方法的接口類,單看接口類,咱們只能知道這個模板有哪些抽象方法以及這些方法的調用順序,但最終這些方法具體作什麼操做,僅從模板類沒法得知。繼承模板的不一樣的子類,對這些抽象方法能夠有不一樣的實現,當父類的模板方法被調用時,程序就能夠有不一樣的行爲實現。算法

  像這樣,在父類中定義處理流程的框架,在子類中實現具體處理的模式,稱爲模板方法模式。spring

  在一般的面向對象程序設計中,咱們習慣於站在子類的角度思考問題:例如子類繼承了父類的哪些方法和屬性,子類如何擴展父類實現新的功能,子類如何覆蓋父類的方法來改變程序的行爲。如今換一種角度,站在父類的角度思考子類:期待子類須要實現的抽象方法,要求子類必須實現的抽象方法。這也是Java面向對象程序設計中抽象類設計的特色:抽象類並不說明具體要執行的操做,可是抽象類能夠提早決定繼承它的子類中的方法名(抽象類中的方法名),並定義這些方法的處理流程,這種在抽象階段決定處理流程很是重要:sql

  • 使處理邏輯通用化,父類模板方法中已經寫好了每一個方法調用的時機,並處理這些方法的結果,實現業務算法,所以子類無需重複編寫如何調用這些方法的算法。
  • 在子類中實現父類的抽象方法時,須要充分理解這些抽象方法的調用時機,從而實現子類與父類之間的協做。
  • 父類與子類的一致性,根據里氏替換原則(LSP),可使用父類的變量保存子類的實例,且不管變量保存的是哪一個子類實例,調用父類的模板方法,程序均可以正常工做。

  舉個具體的例子,在程序中訪問數據庫,不管是什麼數據庫(mysql、oracle、h2),要操做它們都要作一些特定步驟的操做:數據庫

  • 1. 創建數據庫鏈接
  • 2. 建立Connection鏈接
  • 3. 建立statement或者preparedStateement
  • 4. 執行sql,返回ResultSet
  • 5. 關閉resultSet
  • 5.關閉statement
  • 6.關閉Connection

  Spring針對不一樣的平臺,提供了幾種不一樣的模板:設計模式

  • 直接使用JDBC:提供了JdbcTemplate
  • 使用ORM框架:HibernateTemplate和JpaTemplate

2、模板方法(Template Method)模式類圖oracle

3、模板方法(Template Method)模式中的角色框架

  • AbstractClass抽象類:負責實現模板方法,並聲明要用到的抽象方法。
  • ConcreteClass具體類:負責實現AbstractClass抽象類中的抽象方法,這些方法會被AbstactClass抽象類中的模板方法調用。

4、代碼示例maven

這裏使用Spring的JDBCTemplate來演示模板方法模式:

1:建立java控制檯應用程序,並添加spring相關依賴(或者使用maven建立java項目),項目目錄結構以下:

注:adapterpattern包和iteratorpattern包是以前設計模式的代碼示例包,無需理會(也能夠查看我以前的博客,裏面有說明這些代碼是如何建立的)。

2:建立數據源的Bean,即上圖中的ContextBeans類:

package com.designpattern.cn.templatemethodpattern;

import org.springframework.context.annotation.Bean;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.stereotype.Component;

import javax.sql.DataSource;

@Component
public class ContextBeans {
    @Bean
    public DataSource dataSource(){
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://10.211.55.100:3306/fruit_sale_system");
        dataSource.setUsername("root");
        dataSource.setPassword("123456");
        return dataSource;
    }
}
View Code

3:啓用Spring容器的自動掃描配置類SpringConfig:

package com.designpattern.cn.templatemethodpattern;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan
public class SpringConfig {
}
View Code

4:測試使用模板方法操做數據庫執行結果:

能夠看到上述代碼中,我只進行了Spring的基本配置,併爲項目設置了一個mysql數據源,經過建立模板的實例JdbcTemplate,就能夠直接調用queryForObject模板方法,實現業務查詢。

5、相關的模式

  • 工廠方法(FactoryMethod)模式:工廠方法模式是將模板方法用於生成實例的的典型例子。
  • 策略(Strategy)模式:模板方法模式中,使用繼承來改變程序的行爲,而在策略模式中,使用委託改變程序的行爲,並替換整個算法。
相關文章
相關標籤/搜索