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

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

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

    瘋狂

    STANDING ON THE SHOULDERS OF GIANTS
    posts - 481, comments - 486, trackbacks - 0, articles - 1
      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

    我是如何寫Service的

    Posted on 2010-10-01 17:08 瘋狂 閱讀(1317) 評論(0)  編輯  收藏 所屬分類: java


    文章轉載自:http://kiral.javaeye.com/blog/606348?page=2#comments 原文還包括精彩的討論。
    馬上要告別研發了,所以寫一些自己積累的經驗,用來紀念4年的似水流年,本篇為第一張,用來介紹自己是如何寫Service的,當然我總結的不一定合理,大家一起討論下。

     

    筆者認為,Service及服務層,服務可以分為功能服務和業務服務,功能服務不易改變,業務服務易改變。所以功能服務添加得多,修改的少,那么我們可以考慮不使用接口。而業務服務,修改和更新都很頻繁,所以應該提取接口,用不同的實現來屏蔽業務邏輯。

     

    1:使用斷言控制輸入。

    使用斷言來判斷有效的輸入,這樣能夠避免異常的擴散,迅速定位錯誤和減少BUG出現的幾率。

    如:

    Java代碼 復制代碼
    1. import org.springframework.util.Assert;  
    Java代碼 復制代碼
    1. private boolean addAttachment(Attachment att) {   
    2.   Assert.notNull(att, "att對象不能為空");   
    3. }  

    要學會靈活運用斷言,不僅僅是用來斷言來判斷方法的輸入參數是否正確,還可以判斷業務邏輯,每次方法調用的輸入輸出,至于何時使用需要自己根據方法自我判斷。

     

    2:只拋出RumtimeException

    作為service層,自己不清楚調用方到底是誰,也不知道調用方如何使用自己的接口,那么自己寫出的接口最好是拋出RumtimeException,這樣調用方能夠處理這個異常或者覺得處理這個異常有必要的話,就進行處理。如果使用Exception就得強制那些處理不了的調用方繼續向外拋出。拋出RumtimeException的時候需要在注釋里申明我拋出了該異常。

    Java代碼 復制代碼
    1. throw new RuntimeException("工作流初始化失敗!");  

     

    3:在Service層做事務處理

    大家都知道Service層一般是用來組合DAO,所以經常出現需要事務處理的地方,筆者建議盡量在service層做事務處理。

    因為一般業務邏輯都屏蔽在service層。筆者習慣使用Spring的手動事務。

    Java代碼 復制代碼
    1. new TransactionTemplate(transactionManager).execute(new TransactionCallbackWithoutResult() {      
    2.             protected void doInTransactionWithoutResult(TransactionStatus status) {      
    3.                 //調用DAO按照ID刪除部門      
    4.             }      
    5. });     

     

     

    4:Service接口的異常處理

    對于程序異常,service能夠處理的自己處理(將異常封裝成自己的異常,再向外拋出也算一種處理),不能處理的繼續向外拋出。

    對于業務異常,以前開發的時候都會向外拋出一個用戶友好的運行時異常,這種異常信息是能夠直接展現給用戶的,如“您添加的用戶名已經存在!”,但是現在考慮到國際化,所以覺得Service的接口應該拋出錯誤代碼,定義一個友好錯誤代碼運行時異常,在程序出現條件錯誤的時候拋出錯誤代碼。錯誤代碼可以定義一個枚舉類來實現。

    Java代碼 復制代碼
    1. /**  
    2.  * 錯誤代碼定義  
    3.  *  
    4.  * @author fangtengfei  
    5.  * @date   2010-3-3  
    6.  */  
    7. public enum ErrorCode {   
    8.     /**  
    9.      * 用戶不能重復  
    10.      */  
    11.     User_Not_Repeat,   
    12.     /**  
    13.      * 用戶名太長  
    14.      */  
    15.     User_Name_Too_Long   
    16. }  
    Java代碼 復制代碼
    1. 在Service里拋出:throw new FriendlyCodeRuntimeException(ErrorCode.User_Not_Repeat.toString());  

      

     

    5:必須記錄日志

      大家都知道,記錄日志的目的,主要是當程序運行在不同的環境下,使用日志來監控程序的運行,有些異常可能會特定的環境發生,而這種環境不容易被重現,所以此時唯一能定位問題的途徑就只有日志。

    Service層會被各種調用方使用,特別是對外提供Service,環境更會前差萬別,如何迅速并有效的定位錯誤變得尤其重要,所以必須記錄有效的日志。

    Java代碼 復制代碼
    1. logger.error("更新文檔出現出錯", e);  

     

     6:寫有效的注釋

    之所以說寫有效的注釋,是因為有時候,有些方法真的不需要寫注釋,如addUser,就不要在寫注釋“添加用戶”這樣的注釋。關鍵是寫有效的注釋,注釋的作用在于,調用方只看注釋而不看代碼就能知道如何使用接口,注釋應該包括:輸入參數的注釋,輸出參數的注釋和異常的注釋。特別是List<Map>,Sting[]這樣的參數要嚴格說明,筆者認為Service作為一個核心層,注釋必須非常詳細。另外直觀的方法名也能起到注釋的作用。

    Java代碼 復制代碼
    1. /**  
    2. * 批量添加文檔的附件   
    3.  
    4. * @param att 附件對象,附件名長度為20,附件大小為10M  
    5. * @throws FriendlyCodeRuntimeException  
    6.  */  
    7. private void addAttachment(Attachment... attachment)  
    主站蜘蛛池模板: 亚洲熟妇无码一区二区三区| 亚洲永久永久永久永久永久精品| 中文无码日韩欧免费视频| 麻豆精品国产免费观看| 亚洲日韩AV一区二区三区四区 | 久久久久免费精品国产| 亚洲人成中文字幕在线观看| 国产精品成人69XXX免费视频| 亚洲香蕉网久久综合影视| 99久久成人国产精品免费| 亚洲色偷拍另类无码专区| 无码国产精品一区二区免费式芒果| 久久久久亚洲精品成人网小说| 日本系列1页亚洲系列| 免费永久国产在线视频| 高h视频在线免费观看| 亚洲一区精品无码| 久久久久国产精品免费免费不卡| 亚洲国产成人精品无码一区二区| 成年在线网站免费观看无广告| 国产精品亚洲а∨无码播放| 久久国产精品成人免费| 亚洲一区二区三区高清视频| 在线观看国产情趣免费视频| 一个人晚上在线观看的免费视频| 亚洲av无码精品网站| 亚洲免费综合色在线视频| 亚洲男人的天堂在线播放| 综合在线免费视频| 噜噜综合亚洲AV中文无码| 扒开双腿猛进入爽爽免费视频| 特级毛片全部免费播放a一级| 亚洲色偷拍另类无码专区| 日日麻批免费40分钟日本的| 亚洲精品国产suv一区88| 无码中文字幕av免费放| 有码人妻在线免费看片| 亚洲成人福利在线| 亚洲第一黄片大全| 久热中文字幕在线精品免费| 男女作爱免费网站|