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

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

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

    posts - 56, comments - 77, trackbacks - 0, articles - 1
      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

    Validation 問題域

    Posted on 2010-06-28 22:01 切爾斯基 閱讀(2214) 評論(4)  編輯  收藏
    • 誰來做Validation
    • 何時做Validation
    • 如何表達錯誤
    • 如何傳遞錯誤
    • 如何關聯錯誤到發生錯誤的對象, 尤其是對象圖中非Root對象



    這里的Validation指的是對進入到系統中的業務數據的校驗(不包括Web應用中頁面數據在瀏覽器端的驗證)

    誰來做Validation


    數據的有效性不是自身所能決定的, 而是使用它的場景(Context)決定的, 因此, 每個Context應該有自己的Validation邏輯.

    一個例子, 個人信息殘缺, 比如婚姻狀況沒填, 但聯系地址電子郵件等信息完備, 那么這個個人信息到底是合法還是非法? 如果你的應用是個稅務相關的應用必須知道婚姻狀況則數據是非法的, 如果你的應用是CRM系統有客戶的聯系方式即可而婚姻狀況是可選的則數據就是合法的. 問題是你的應用是稅務應用但同時支持客戶關系管理, 那這段數據到底合法非法? 稅務應用只是年底的時候才有人用, 而客戶關系管理系統隨時都有人用, 假設數據是通過頁面提交的, 那這批數據到底該拒絕還是接受?

    何時做Validation


    通常有幾個時機, 對象被創建出來, 對象狀態改變, 以及對象被持久化. 企業應用中同一份數據一般至少有兩種存在形式: 在數據庫中的持久化狀態, 以及在內存中以編程語言定義的對象形式存在. 那么幾個時機:

    • 手動創建對象, 就是應在構造函數中做驗證
    • 框架幫忙創建對象, 比如從頁面Form綁定到Server端的對象時, 可以在綁定完成的那一刻做校驗
    • 存到數據庫里那一刻


    這就帶來一個問題: 可能要在三個地方做大體相同的驗證, 如何復用驗證規則?
    另一個問題是: 在引入ORM的應用中, 編程語言寫好的驗證邏輯同樣可以應用在持久化到數據庫的那一顆, 那在SQL/DDL語句中定義的約束是否還必要?

    如何表達錯誤


    有兩個約束:

    • 要提供易于用戶和支持人員理解的錯誤信息
    • 要提供盡可能豐富的信息


    常見的手段是用字符串或者錯誤代碼/ID, 這是不work的, 因為它們合并了錯誤本身和錯誤的表示:

    出錯的地方可能距離需要展現錯誤的地方很遠, 或者有多種展現錯誤的界面, 或者有很多顯示方面的需求, 比如支持國際化, 報錯的地方是沒有能力也不需要知道錯誤是如何被展示的, 它要做的是盡可能報告關于錯誤的詳細信息, 包括違反了什么規則, 出錯的字段, 實際的值和期待的值等, 字符串和錯誤代碼/ID是沒有如此豐富的表達能力的

    我們可以用對象來表達錯誤信息, 對象的類型可以表示錯誤的類別, 對象的屬性/字段可以攜帶各種與錯誤類型相關的數據. 然后在需要展現給用戶的那一刻, 再把對象翻譯成針對那個界面的顯示, 比如可以做國際化, 或者提供給程序員更技術化的描述. 而在錯誤信息需要被顯示之前, 錯誤在系統中的傳遞, 都是以對象的形式進行的...

    聽起來跟異常Exception很像?

    幾個反例是.Net平臺上的異常, 比如KeyNotFoundException, 它就不告訴你那個找不到的Key是啥, 還有Index越界, 就不告訴你index的值是多少, 還有數據庫連接超時或者Transaction Timeout,死活不告訴你它等了多久超時的, 讓你搞不清楚是你的超時時間設的太短還是根本你的設置就沒生效

    如何傳遞錯誤


    收集參數, 輸出參數, Thread Local, 或者拋出異常然后合適的層次捕獲

    如何關聯錯誤到發生錯誤的對象圖, 尤其是對象圖中非Root對象


    給錯誤一個Key, 這個Key應該能表示出錯的對象在對象圖中的位置, 比如Key可以是字段名稱中間用"."分隔, 級聯起來的字符串. 注意這種形式的key應該是在調用驗證邏輯的地方組裝起來的, 而不應該是驗證邏輯本身, 因為驗證邏輯通常并不知道自己驗證的這個對象在父對象中的字段名稱

    一個額外的話題

     

    很多驗證框架采用了基于Attribute/Anontation的方式, 這樣當一個對象在不同的Context有不同的驗證邏輯時就會很糾結, 因為它是以侵入的方式寫到對象的定義中的. 這恰恰從另一個角度說明了對象是不應該跨Context復用的, DCI才是王道


    評論

    # re: Validation 問題域[未登錄]  回復  更多評論   

    2010-06-28 23:06 by anders小明
    不僅僅是validation,甚至是業務操作,在不同上下文下都是不同的。
    所以雖然很煩xml,但是更怕attribute/annotation,
    折中的方法:
    1.越是外圍的對象,比如界面層,采用annotations;
    2.越是核心的對象,比如服務/規則,采用xml配置,但采用帶有一定能夠verbose特性的命名空間定義;

    # re: Validation 問題域  回復  更多評論   

    2010-06-29 00:36 by 切爾斯基
    @anders小明

    是啊, 類型是強依賴, 具體類型更是強中之強, 配置文件是最弱的依賴, 但帶來的問題就是運行時管理問題, 還是上一篇提到的, 部署時如何識別或標識依賴然后打包的問題

    # re: Validation 問題域[未登錄]  回復  更多評論   

    2010-06-29 10:46 by Robin
    弱問DCI是什么東東?

    # re: Validation 問題域  回復  更多評論   

    2010-06-29 11:41 by anders
    關于DCI:
    http://www.infoq.com/cn/news/2009/05/dci-coplien-reenskau

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


    網站導航:
    博客園   IT新聞   Chat2DB   C++博客   博問  
     
    主站蜘蛛池模板: 亚洲精品国产综合久久久久紧| 亚洲精品国产手机| 国产亚洲精品美女久久久久 | 亚洲国产精品无码久久久蜜芽| 美女羞羞免费视频网站| 亚洲国产高清精品线久久| 成在线人直播免费视频| 亚洲精品天堂成人片?V在线播放| 夜夜爽妓女8888视频免费观看| 伊人久久亚洲综合影院| 人成午夜免费大片在线观看| 亚洲国产一区明星换脸| 一个人看的免费观看日本视频www 一个人看的免费视频www在线高清动漫 | 成人性生交大片免费看无遮挡 | 911精品国产亚洲日本美国韩国 | 菠萝菠萝蜜在线免费视频| 亚洲第一区在线观看| 精品久久久久久无码免费| 亚洲精品少妇30p| 久久黄色免费网站| 色婷婷亚洲十月十月色天| 成人黄色免费网站| 亚洲狠狠婷婷综合久久蜜芽| 免费人成在线观看播放国产| 一级毛片免费播放视频| 亚洲国产a∨无码中文777| 在线观看免费视频资源| 亚洲色欲色欲www在线播放| www.亚洲色图| 中文字幕无码一区二区免费| 亚洲成人福利网站| 日韩一区二区三区免费体验| 久香草视频在线观看免费| 日产亚洲一区二区三区| 午夜男人一级毛片免费| 一边摸一边爽一边叫床免费视频| 狠狠色伊人亚洲综合成人| 一本无码人妻在中文字幕免费| 黄页视频在线观看免费| 亚洲福利在线视频| 日本免费人成黄页在线观看视频|