java設計模式之模板模式以及鈎子方法使用


 正文前先來一波福利推薦:

 福利一:

百萬年薪架構師視頻,該視頻可以學到很多東西,是本人花錢買的VIP課程,學習消化了一年,為了支持一下女朋友公眾號也方便大家學習,共享給大家。

福利二:

畢業答辯以及工作上各種答辯,平時積累了不少精品PPT,現在共享給大家,大大小小加起來有幾千套,總有適合你的一款,很多是網上是下載不到。

獲取方式:

微信關注 精品3分鍾 ,id為 jingpin3mins,關注后回復   百萬年薪架構師 ,精品收藏PPT  獲取雲盤鏈接,謝謝大家支持!

-----------------------正文開始---------------------------

 

1、使用背景

  模板方法模式是通過把不變行為搬到超類,去除子類里面的重復代碼提現它的優勢,它提供了一個很好的代碼復用平台。當不可變和可變的方法在子類中混合在一起的時候,

不變的方法就會在子類中多次出現,這樣如果摸個方法需要修改則需要修改很多個,雖然這個這個問題在設計之初就應該想好。這個時候模板方法模式就起到了作用了,

通過模板方法模式把這些重復出現的方法搬到單一的地方,這樣就可以幫助子類擺脫重復不變的糾纏。

2、已Spring中的  JdbcTemplate 使用模板模式為例  說明其優越之處;

方法 execute(StatementCallback<T> sc) 方法公共方法,里邊封裝了可復用代碼;

參數StatementCallback是一個接口 接口方法是 doInStatement() 該方法是實現不同操作的方法;也就是不同的實現在這里呈現;

public <L> L execute(StatementCallback<L> action)
    {
          
        try{ 
                    1. 加載驅動 2. 建立連接 3. 獲取Statement stmt
            4. 拼接參數

}
catch(Exception e) { }

try{

  synchronized (this) //使用同步鎖 保護線程安全
  {
    return action.doInStatement(session);
  }
}
catch (HibernateException ex)
{
  
throw new Exception(ex);
}
catch (SQLException ex) {
}

finally{ 7. 銷毀連接 } } }

 

@Override
public <T> T query(final String sql, final ResultSetExtractor<T> rse) throws DataAccessException {
    Assert.notNull(sql, "SQL must not be null");
    Assert.notNull(rse, "ResultSetExtractor must not be null");
    if (logger.isDebugEnabled()) {
        logger.debug("Executing SQL query [" + sql + "]");
    }
    //匿名內部類
    class QueryStatementCallback implements StatementCallback<T>, SqlProvider {
        @Override
        public T doInStatement(Statement stmt) throws SQLException { ResultSet rs = null; try { rs = stmt.executeQuery(sql); ResultSet rsToUse = rs; if (nativeJdbcExtractor != null) { rsToUse = nativeJdbcExtractor.getNativeResultSet(rs); } return rse.extractData(rsToUse); } finally { JdbcUtils.closeResultSet(rs); } }
        @Override
        public String getSql() {
            return sql;
        }
    }
    //真正執行的方法
    return execute(new QueryStatementCallback());
}

 

調用query方法的時候 會執行execute方法,該方法為模板方法,然后因為該方法內部調用傳入的 StatementCallback 接口的 doInStatement 方法 但是該方法可以在query方法中通過傳入匿名內部類,自定義使用; 完全符合模板模式的使用;

1、使用鈎子方法對模板不同行為進行控制

下面以一個汽車的例子來說明鈎子方法的使用:

public abstract class HummerModel {
    protected abstract void start(); //發動
    protected abstract void stop();  //停止
    protected abstract void alarm(); //鳴笛
    protected abstract void engineBoom(); //轟鳴
    final public void run() { //車總歸要跑
        this.start();
        this.engineBoom();
        if(this.isAlarm()) {//想讓它叫就叫,不想就不叫        
            this.alarm();
        }
        this.stop();
    }
    protected boolean isAlarm() { //我們加了一個判斷方法,默認返回true
        return true;
    }
}

 

public class HummerH1 extends HummerModel {
 
    private boolean alarmFlag = true; //判斷標記
    @Override
    public void start() {
        System.out.println("H1發動……");
    }
 
    @Override
    public void stop() {
        System.out.println("H1停止……");
    }
 
    @Override
    public void alarm() {
        System.out.println("H1鳴笛……");
    }
 
    @Override
    public void engineBoom() {
        System.out.println("H1轟鳴……");
    }
    
 @Override protected boolean isAlarm() { //覆寫isAlarm方法,返回判斷標記 return this.alarmFlag; } public void setAlarm(boolean isAlarm) { //設置判斷標記
        this.alarmFlag = isAlarm;
    }
    
}

 

這段代碼中,我們在模板方法中增加了判斷標記,然后子類對外提供一個public接口setAlarm來讓外界設置這個判斷標記,這個判斷標記就像是開關一樣,想讓它ture和false都行。
這個isAlarm方法俗稱鈎子方法。有了鈎子方法的模板方法模式才算完美,使得我們的控制行為更加的主動,更加的靈活。

 
       


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM