服務層的必要性
捕獲異常
調試某個項目,搭建好環境,打開首頁,然后是一個大黃頁(500),錯誤信息是NullReferenceException。然后Debug了 一下代碼,原來數據庫連接字符串錯誤,作者在DBHelper中捕獲了異常,這樣DBHelper里的方法的返回值就是一個null。對于這樣的 try...catch...我也是醉了,我表達的意思在這種情況下,不捕獲異常要比捕獲異常好很多。捕獲了異常引發了其他的錯誤,更浪費開發人員的時 間。我敢肯定我絕對不是第一個被這樣的代碼坑的,也不會是最后一個。既然在DBHelper捕獲異常不正確,那么應該在哪里捕獲異常呢?我的建議是統一捕 獲,數據訪問層不適合捕獲異常,因為數據訪問層的定位是專注于數據訪問,業務邏輯層亦不適合捕獲異常,因為業務邏輯層專注于領域邏輯和應用邏輯的處理。數 據訪問層和業務邏輯層只要專注于能夠正確的執行就好。 這個時候就需要在業務邏輯層之上再搭建一層,這層就是服務層,如圖
(圖片來源 http://www.cnblogs.com/DotCpp/p/4291113.html )
將捕獲異常和處理錯誤的代碼放在服務層中。
并不是所有拋出的異常都在service中去捕獲,主要還是看異常場景,
- 異常已經造成了當前執行流程的阻斷就需要在service層捕獲。
- 異常引發流程控制,并不需要阻斷當前流程。舉個例子先請求A,若A異常了,則在請求B。這樣的情況就可以在當前代碼捕獲異常。
.NET異常模型,對于開發者是友好的,但是對于用戶來說并不友好,比如出現了異常,就展現一個大黃頁,用戶會不知所措。用戶希望看到的是友好的 提示信息,而不是錯誤編碼和堆棧信息。這個時候我們就需要對錯誤模型轉換,由Exception轉化為錯誤編碼。在UI層通過錯誤編碼以合理的方式將信息 展現給用戶。
業務邏輯協調
對于交易這種復雜的業務流程來說,完成這樣的一個流程需要若干個子業務流程協同完成。舉個例子,假設最初買一件衣服需要兩個流程
- 將錢充值賬戶,寫充值記錄;
- 使用賬號購買衣服,寫消費記錄;
這兩個流程是分別進行的,即向買件衣服之前必須向賬號內充值。有一天,PM意識到這個事情對用戶太不友好了,所以就需要這兩個流程一氣呵成,但是 想一氣呵成需要解決一系列的問題,如充值流程不成功、衣服下架,需要退款。這就出現了很多協調這兩個流程的業務邏輯,甚至會衍生出新的業務邏輯比如退款。 那么協調這部分業務邏輯的代碼應該放哪兒? 放UI層不合理的,因為UI層主要負責表現業務邏輯處理,用戶參數校驗等。所以我們需要新添加一個層,這個層就是業務外觀層,來做業務流程協調。