設計模式——模板模式

          所謂模板,當然是一個通用的模型,他要把一成不變的事物提取出來,之后在其中加入個性的操作,來完成我們的需求。恰當的在程序設計中使用模板模式能夠大大的縮短開發周期及代碼量,這樣一來,既能保證程序中各個模塊的規范統一,又能減少BUG。

          學習設計模式一定通過實例來驅動,spring和JDBC的整合就可以看到模板模式的身影
          一般來說,使用JDBC操作數據庫無非以下幾個步驟
          1,創建數據源并獲取連接
          2,通過連接創建預定義的查詢
          3,設定查詢的參數
          4,新建結果集接收查詢返回的結果
          而這些步驟中,1和4是每一次操作所必須的,而2和3才是開發者需要自定義的,spring抽取了這些公共的操作,把自定義操作通過接口暴露給開發者,恰當的運用了模板模式。
          拿出一個spring整合JDBC中UserDao的例子,撇開整合的過程,單看jdbcTemplate,我們給jdbcTemplate傳入SQL語句和指定的參數,就完成了對數據庫的更新,公共的操作我們則不需要去擔心
           1 @Repository("userJdbcDao")
           2 public class UserDao implements IUserDao {
           3 
           4     private JdbcTemplate jdbcTemplate;
           5 
           6     //在此注入datasource創建jdbcTemplate
           7     @Resource
           8     public void setDataSource(DataSource dataSource) {
           9         this.jdbcTemplate = new JdbcTemplate(dataSource);
          10     }
          11 
          12     /**
          13      * 更新
          14      */
          15     public void update(User user) {
          16         jdbcTemplate.update("update t_user set name = ? where id = ?",
          17                 user.getName(), user.getId());
          18     }
          19 }
          模擬spring模板的功能,通過繼承的方式來實現一個模板,自定義一個模板
           1 package org.duyt.template;
           2 
           3 public abstract class JdbcTemplateByInherit {
           4     /**
           5      * 公共操作:開啟連接
           6      */
           7     private void beginCon(){
           8         System.out.println("開啟連接");
           9     }
          10     /**
          11      * 公共操作:關閉連接
          12      */
          13     private void closeCon(){
          14         System.out.println("關閉連接");
          15     }
          16     /**
          17      * 模板方法,套用公共操作,添加個性操作
          18      */
          19     public void execute(){
          20         beginCon();
          21         run();
          22         closeCon();
          23     }
          24     /**
          25      * 個性方法,暴露給繼承的子類
          26      */
          27     public abstract void run();
          28 }
          29 
          繼承類
           1 package org.duyt.template.impl;
           2 
           3 import org.duyt.template.JdbcTemplateByInherit;
           4 
           5 public class UserDaoByIn extends JdbcTemplateByInherit{
           6 
           7     /**
           8      * 添加自定義操作
           9      */
          10     @Override
          11     public void run() {
          12         System.out.println("執行了run方法");
          13     }
          14 
          15 }
          16 
          測試一下
           1 package org.duyt.test.template;
           2 
           3 import org.duyt.template.JdbcTemplateByInherit;
           4 import org.duyt.template.impl.UserDaoByIn;
           5 import org.junit.Test;
           6 
           7 public class TestJdbcTempbyinherit {
           8     
           9     @Test
          10     public void test01(){
          11         JdbcTemplateByInherit dao = new UserDaoByIn();
          12         dao.execute();
          13     }
          14 
          15 }
          16 
          結果:
          開啟連接
          執行了run方法
          關閉連接
          雖然看上去很簡陋,但是至少已經有了一個模板的雛形。在模板方法中,我們還可以使用“鉤子函數”來控制模板方法的流程,在模板中添加鉤子函數暴露給實現類,并修改模板方法
           1     /**
           2      * 模板方法,套用公共操作,添加個性操作
           3      */
           4     public void execute(){
           5         beginCon();
           6         if (ishookerOnOrOff()) {
           7             run();
           8         }
           9         else{
          10             System.out.println("不執行任何操作");
          11         }
          12         
          13         closeCon();
          14     }
          15     /**
          16      * 個性方法,暴露給繼承的子類
          17      */
          18     public abstract void run();
          19     
          20     /**
          21      * 鉤子方法,可以用來控制模板方法的流程
          22      * @return
          23      */
          24     public abstract boolean ishookerOnOrOff();
          修改實現類,添加鉤子方法的實現
          1     @Override
          2     public boolean ishookerOnOrOff() {
          3         return false;
          4     }
          測試結果:
          開啟連接
          不執行任何操作
          關閉連接

          現在回頭看到jdbcTemplate,他并沒有通過任何實現類去繼承這個模板來調用或控制模板方法的流程,而是直接使用模板來對數據庫進行操作,這樣一來,就不能使用繼承的方式來使用模板,要升級鉤子,使用接口,使得外界能夠直接使用模板方法。新建一個鉤子接口
          1 package org.duyt.template;
          2 
          3 import java.util.Map;
          4 
          5 public interface GenericDaoMethod {
          6     public void invoke(String sql,Map params);
          7 }
          8 
          新建一個通過以組件形式出現的模板JdbcTemplateByComponent
           1 package org.duyt.template;
           2 
           3 import java.util.Map;
           4 
           5 public class JdbcTemplateByComponent {
           6 
           7     private void beginCon(){
           8         System.out.println("開啟連接");
           9     }
          10 
          11     private void closeCon(){
          12         System.out.println("關閉連接");
          13     }
          14     
          15     public void execute(GenericDaoMethod genericDaoMethod,String sql,Map params){
          16         beginCon();
          17         genericDaoMethod.invoke(sql,params);
          18         closeCon();
          19     }
          20     
          21     public void add(String sql,Map params){
          22         execute(new GenericDaoMethod() {
          23             public void invoke(String sql, Map params) {
          24                 System.out.println(sql);
          25                 System.out.println(params);
          26                 //使用創建的con,preparedstatement,resultset結合Sql和params執行CURD
          27             }
          28         }, sql, params);
          29     }
          30     ......其他方法略
          31     
          32 }
          33 
          我們看到,通過組建的方式來創建模板,需要將所有的待暴露方法都定義好在模板里,并且在每個方法中都需要實現各自的鉤子方法來使用模板方法,而對于外界,也就是調用者,只需要關心傳入的參數,和調取的方法能夠實現的業務,無需關心連接,查詢和結果集的開關等操作。基于這個思路,就基本實現了對數據庫操作的模板。

          posted on 2014-11-08 16:34 都較瘦 閱讀(119) 評論(0)  編輯  收藏 所屬分類: DesignPattern


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          <2025年6月>
          25262728293031
          1234567
          891011121314
          15161718192021
          22232425262728
          293012345

          導航

          統計

          公告

          博客定位:囿于目前的水平,博客定位在記錄自己的學習心得和隨手的練習

          常用鏈接

          留言簿

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 宿州市| 丽江市| 静宁县| 忻城县| 郴州市| 万载县| 禹州市| 正安县| 静安区| 新津县| 迁安市| 宁国市| 龙州县| 酉阳| 时尚| 精河县| 景东| 凤山市| 呈贡县| 商洛市| 枣强县| 尤溪县| 四平市| 岱山县| 万全县| 藁城市| 桃园县| 天祝| 沁水县| 胶南市| 丰台区| 昌黎县| 凤冈县| 宜城市| 建平县| 梁平县| 义乌市| 丁青县| 阿拉善右旗| 淮阳县| 和顺县|