<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    春風博客

    春天里,百花香...

    導航

    <2008年9月>
    31123456
    78910111213
    14151617181920
    21222324252627
    2829301234
    567891011

    統計

    公告

    MAIL: junglesong@gmail.com
    MSN: junglesong_5@hotmail.com

    Locations of visitors to this page

    常用鏈接

    留言簿(11)

    隨筆分類(224)

    隨筆檔案(126)

    個人軟件下載

    我的其它博客

    我的鄰居們

    最新隨筆

    搜索

    積分與排名

    最新評論

    閱讀排行榜

    評論排行榜

    使用模板方法模式簡化控制層類(Action)的設計

    在基于Model2的應用中,控制層的類總會包含對業務層諸類的調用,業務層諸類不可避免的要產生各種異常,如果統一到控制層進行處理的話會導致代碼變得龐大臃腫還有不少重復,這種的例子在Web應用中的Servlet和Action諸類中并不少見。

    如果我們使用模板方法模式(Template Method Pattern)將業務處理和異常處理分開,能有效簡化控制層諸類的代碼,借用這種模式,我們可以把固定的異常處理代碼放在基類中,而讓子類來實現具體的業務,如果執行業務過程中出現異常如數據庫無法連接,用戶找不到等異常后,直接將異常拋出讓基類來處理,這樣做成功的把業務處理和異常處理分開到了子類和基類兩種類中,涉及具體業務處理的子類代碼得到了很大的簡化,更方便閱讀,修改和管理。

    具體請參考以下代碼:

    諸Action的基類,包含了所有的異常處理,它是一個抽象類,規定子類必需實現process函數:
    package com.heyang.action.base;

    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;

    import org.apache.struts.action.Action;
    import org.apache.struts.action.ActionForm;
    import org.apache.struts.action.ActionForward;
    import org.apache.struts.action.ActionMapping;
    import org.springframework.dao.DataAccessResourceFailureException;
    import org.springframework.dao.DataIntegrityViolationException;
    import org.springframework.dao.InvalidDataAccessResourceUsageException;
    import org.springframework.dao.TypeMismatchDataAccessException;

    import com.heyang.domain.User;
    import com.heyang.exception.database.CannotFindRecordByIdException;
    import com.heyang.exception.database.OneIdMultiRecordException;
    import com.heyang.exception.user.CannotFindUserInSessionException;
    import com.heyang.exception.user.ErrorPswdException;

    /**
     * 各個Action的基類
     * 
    @author 何楊(heyang78@gmail.com)
     *
     * 
    @since 2008-8-29 上午09:00:48
     * 
    @version 1.00
     
    */

    public abstract class BizBaseAction extends Action {
        
    public ActionForward execute(ActionMapping mapping, ActionForm form,
                HttpServletRequest request, HttpServletResponse response)
                
    throws Exception {
            
            request.setCharacterEncoding(
    "UTF-8");
                    
            
    try{
                
    return process(mapping,form,request,response);
            }

            
    catch(CannotFindUserInSessionException ex){
                
    // 用戶名不存在
                request.setAttribute("msg""在session中找不到用戶,要執行操作請先登錄");            
                
    return new ActionForward("/web/page/login.jsp");
            }
     
            
    catch(CannotFindRecordByIdException ex){
                
    // 用戶名不存在
                request.setAttribute("msg""用戶名不存在,請重新輸入");            
                
    return new ActionForward("/web/page/login.jsp");
            }
      
            
    catch(ErrorPswdException ex){
                
    // 用戶登錄密碼錯誤
                request.setAttribute("msg""密碼錯誤,請重新輸入");            
                
    return new ActionForward("/web/page/login.jsp");
            }

            
    catch(OneIdMultiRecordException ex){
                
    // 系統發生重大問題,一個用戶名對應著多條記錄
                request.setAttribute("feedbackTitle""系統發生重大問題");
                request.setAttribute(
    "feedbackConcept""系統發生重大問題,成員用戶名對應著多條記錄,報告此錯誤的郵件已經發給系統管理員,請耐心等候處理。");
                
    return new ActionForward("/web/page/result.jsp");
            }
              
            
    catch(TypeMismatchDataAccessException ex){
                request.setAttribute(
    "feedbackTitle""Java類型和數據類型不匹配.");
                request.setAttribute(
    "feedbackConcept""錯誤信息為"+ex.getMessage());
                
    return new ActionForward("/web/page/result.jsp");
            }

            
    catch(DataAccessResourceFailureException ex){
                request.setAttribute(
    "feedbackTitle""無法連接到數據庫,請檢查數據庫連接是否正確.");
                request.setAttribute(
    "feedbackConcept""錯誤信息為"+ex.getMessage());
                
    return new ActionForward("/web/page/result.jsp");
            }

            
    catch(DataIntegrityViolationException ex){
                request.setAttribute(
    "feedbackTitle""Insert或Update數據時違反了完整性.");
                request.setAttribute(
    "feedbackConcept""錯誤信息為"+ex.getMessage());
                
    return new ActionForward("/web/page/result.jsp");
            }

            
    catch(InvalidDataAccessResourceUsageException ex){
                request.setAttribute(
    "feedbackTitle""使用錯誤的SQL語句或數據訪問關系型數據庫.");
                request.setAttribute(
    "feedbackConcept""錯誤信息為"+ex.getMessage());
                
    return new ActionForward("/web/page/result.jsp");
            }

            
    catch(Exception ex){
                request.setAttribute(
    "feedbackTitle""未知的錯誤");
                request.setAttribute(
    "feedbackConcept""錯誤信息為"+ex.getMessage());
                
    return new ActionForward("/web/page/result.jsp");
            }

        }

        
        
    /**
         * 留待子類實現業務
         * 
    @param mapping
         * 
    @param form
         * 
    @param request
         * 
    @param response
         * 
    @return
         * 
    @throws Exception
         
    */

        
    protected abstract ActionForward process(ActionMapping mapping, ActionForm form,
                HttpServletRequest request, HttpServletResponse response)
        
    throws Exception ;

        
        
    /**
         * 從Session中找出登錄用戶
         * 
    @param request
         * 
    @return
         * 
    @throws CannotFindUserInSessionException
         
    */

        
    protected User getUser(HttpServletRequest request) throws CannotFindUserInSessionException{
            
    // 從Session中取得用戶
            User user = (User) request.getSession().getAttribute("user");
            
    if (user == null{
                
    throw new CannotFindUserInSessionException("在session中找不到用戶");
            }

            
            
    return user;
        }

    }


    子類之一loginAction,只需實現簡短的process函數即可,所有異常拋出由基類處理:
    package com.heyang.action;

    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;

    import org.apache.struts.action.ActionForm;
    import org.apache.struts.action.ActionForward;
    import org.apache.struts.action.ActionMapping;

    import com.heyang.action.base.BizBaseAction;
    import com.heyang.domain.User;
    import com.heyang.service.UserService;
    import com.heyang.util.ReqUtil;
    import com.heyang.util.SpringUtil;

    /**
     * 用于用戶登錄的Action
     * 
    @author 何楊(heyang78@gmail.com)
     *
     * 
    @since 2008-8-29 上午09:00:48
     * 
    @version 1.00
     
    */

    public final class LoginAction extends BizBaseAction {
        
    public ActionForward process(ActionMapping mapping, ActionForm form,
                HttpServletRequest request, HttpServletResponse response)
                
    throws Exception {
            request.setCharacterEncoding(
    "UTF-8");
            
            
    // 取得參數
            String name = ReqUtil.getFormProperty("name",form);
            String pswd 
    = ReqUtil.getFormProperty("pswd",form);
                
            
    // 取得Service
            UserService service=SpringUtil.getUserService();        
            
            
    // 取得用戶
            User user=service.getUser(name, pswd);
            request.getSession().setAttribute(
    "user", user);
            
    return new ActionForward("/ShowBlocks.do");
        }

    }

    這樣完成以后,對子類來說,只需要關心業務代碼即可,出現異常后的處理和轉向都由基類規定的模板方法完成,這正是模板方法模式給我們帶來的好處。有點疑惑的是,現在還不確定這樣做會有什么消極印象,如安全性或結構方面的,大家要是覺得有問題請不吝賜教。

    posted on 2008-09-01 11:51 sitinspring 閱讀(2207) 評論(8)  編輯  收藏 所屬分類: Object Orient ProgrammingSSH

    評論

    # re: 使用模板方法模式簡化控制層類(Action)的設計 2008-09-01 14:14 zhuxing

    更多的公共代碼的放置問題,骨架突出的成份小  回復  更多評論   

    # re: 使用模板方法模式簡化控制層類(Action)的設計 2008-09-01 14:38 隔葉黃鶯

    現在流行的MVC框架,如 Struts1/Struts2/WebWork/Spring MVC 都能以配置的方式來處理異常,也不需在基類 Action 中處理。
    你的 Action 執行方法只需往框架拋異常,配置一個 ExeptionHandler 就會處理控制層拋出的異常,這樣的做法讓控制層和異常處理類解耦。
    不像你的 BaseAction 實際與異常處理綁定到一起了,我原來的項目也是會寫這么一個 BaseAction,后來更細致了解一下所用的框架就會單獨寫一個異常處理類,配置給框架。  回復  更多評論   

    # re: 使用模板方法模式簡化控制層類(Action)的設計 2008-09-01 15:04 zhuxing

    @隔葉黃鶯
    “尋道者”和你講的不是一個層面的問題。“尋道者”講的是設計模式,你說的框架使用。你這么比,樓主有可能會生氣。

    @隔葉黃鶯
    也斗膽接著聊一下你說的那個問題。從抽象層面講,我們如果想要處理一個行為的變化,一般需要干這幾件事情:
    抽象變化,封裝變化
    數據上下文
    控制上下文

    這種流行框架中的異常處理配置機制就真的好嗎,如果用戶想進行自定義的控制下文呢(例如摟主文中的)???如果數據上下文變化較為頻繁呢???(當然,這可能是由于起初對需求抽象不夠,對已知擴展沒有做詳細分析)

    我們再切換到另外一個角度來看這個問題,任何一個框架肯定就是提供可復用的數據和行為。這種異常處理的配置機制暫且看作框架提供的行為支持吧。 那我可能會問了?我一個業務處理過程本身就包含了異常處理,我干嗎再去配啊,而且給我分開了,以后還要維護這個配置文件???

    這種異常配置的機制有它的好處,也有它的適用場景,再一個那就是取決于開發者的嗜好....

    @隔葉黃鶯:我只是有興趣瞎評論一下,錯誤請指正  回復  更多評論   

    # re: 使用模板方法模式簡化控制層類(Action)的設計 2008-09-01 15:33 隔葉黃鶯

    @zhuxing
    樓主代碼實際用到 Struts,我才說起 struts 框架來,以及它能提供給我們的便利

    看樓主的基類 Action 其實是包含了多種業務的異常處理,作為樓主的替代方式,應該配置一個異常處理類即可,不需要配置多個,所以不涉及到要怎么去維護這個配置文件。如果分業務定義多個基類 Action 來處理異常,又何異于配置多個異常處理類呢?

    當然,與業務非常密緊密的異常,可能放在統一異常處理類里不是很合適。不過要是考慮正常業務邏輯與異常流程分開來,丟給一個 ExceptionHandler 也未嘗不可。

    如果數據上下文變化較為頻繁呢,這時候就要修改基類 Action 處理異常的代碼,這和修改異常處理類也沒多少分別。
      回復  更多評論   

    # re: 使用模板方法模式簡化控制層類(Action)的設計 2008-09-01 15:50 尋道者

    @zhuxing
    @隔葉黃鶯

    兩位都談得很好啊,受益匪淺,本來我寫這個文章就是為了討論和驗證想法的。只要是技術討論,大家暢所欲言吧。

      回復  更多評論   

    # re: 使用模板方法模式簡化控制層類(Action)的設計 2008-09-01 16:12 zhuxing

    @隔葉黃鶯 @尋道者

    一個框架給我們提供了服務的同時,肯定會給我們提供了相應的限制。我覺得,很多時候在決定要使用一個開源框架或者新的方法論(例如AOP)的時候,不但要看到框架的作用,也需要投入很大精力來分析一下框架的短板和限制。當然,是基于我們的需求來分析,如果脫離這一點,那就沒有意義了,純技術去分析一個框架可以當作閑來無事時的消遣~_~  回復  更多評論   

    # re: 使用模板方法模式簡化控制層類(Action)的設計 2008-09-01 17:46 隔葉黃鶯

    @zhuxing
    你的用語很職業,只是我們需要切合這里的實際來討論問題。  回復  更多評論   

    # re: 使用模板方法模式簡化控制層類(Action)的設計 2008-09-01 18:03 zhuxing

    @隔葉黃鶯
    哈哈。
    回到實際,樓主文章中說的主題和異常配置也有點遠,覺得樓主好像意在說一個設計模式
      回復  更多評論   

    sitinspring(http://www.tkk7.com)原創,轉載請注明出處.
    主站蜘蛛池模板: 日韩一级片免费观看| 亚洲AV成人精品日韩一区18p| 综合自拍亚洲综合图不卡区| 97人妻无码一区二区精品免费| 亚洲精品无码人妻无码| 亚洲精品成人a在线观看| 无码人妻一区二区三区免费看| 亚洲xxxxxx| 在线观看午夜亚洲一区| 精品国产免费人成电影在线观看 | 亚洲毛片在线免费观看| 噜噜嘿在线视频免费观看| 嫩草在线视频www免费看| 亚洲日本久久久午夜精品| 亚洲乱码日产精品a级毛片久久| 一级毛片免费毛片一级毛片免费 | 牛牛在线精品观看免费正| 67pao强力打造67194在线午夜亚洲| 麻豆国产精品入口免费观看| 在线播放免费人成毛片乱码| 亚洲AV日韩AV永久无码色欲| 亚洲欧洲日产国码久在线观看| 国产在线观看免费视频播放器| 亚洲免费在线视频| 一级毛片在线完整免费观看| 亚洲图片校园春色| 亚洲国产精品无码专区在线观看| 国产女高清在线看免费观看| 亚洲最大免费视频网| 国产精品九九久久免费视频| 亚洲精品无AMM毛片| 亚洲精品影院久久久久久| 在线观看亚洲精品福利片| 国产成人免费全部网站| 一个人看的www在线观看免费| 182tv免费视频在线观看| 日本永久免费a∨在线视频| 亚洲人成人网站18禁| 亚洲Av高清一区二区三区| 久久噜噜噜久久亚洲va久| 区久久AAA片69亚洲|