取得領先
VMware 提供培訓和認證,以加速您的進步。
瞭解更多大家好!
這是我上個月加入 Interface21 以來的第一篇帖子。我之前的部落格現在已正式棄用,我不會再更新它了。
那麼我第一篇帖子的主題是什麼(除了自我介紹)?驗證邏輯。 這不是如何在 Spring 框架中執行驗證的演練,而是討論我特別討厭的事情:)
特別地,我想討論驗證邏輯中應該包含什麼。這似乎是一個無需動腦筋的答案:“驗證指定資料的邏輯”。好的,這確實是無需動腦筋的,但請繼續閱讀:)。如您所知,Spring 框架透過 Errors 和 Validator 介面為您的驗證提供了一個很好的抽象層。 特別是 Validator 是您將業務特定的驗證規則應用於填充的域物件的地方。 Spring 優秀的繫結支援負責基於某些輸入更新您的域模型,validator 負責確保填充的域模型在語義上是正確的。那麼我討厭的是什麼? 一次又一次,我不斷遇到允許驗證邏輯從 validator 中滲出到控制器(對於 Web 應用程式)的應用程式,甚至更糟的是滲出到中間層。 在人們開始提出異議之前:我不是說驗證不屬於中間層,我是說 Validator 是放置驗證邏輯的地方!
最常見的例子是當您新增新實體時,例如 User。 通常,validator 將執行許多“簡單”檢查(欄位不能為空,文字欄位的長度超過 25 個字元等)。 然後,控制器(例如)將呼叫中間層 (userService.add(user)) 並捕獲 DuplicateKeyException(或強型別的 DuplicateUserException)異常。 如果丟擲此異常,則控制器將填充 errors 物件,然後重新顯示錶單。
那麼這張圖有什麼問題呢? 簡單的事實是,某些驗證現在隱式地透過引發 DuplicateKeyException 來完成,表明驗證失敗! 在插入資料之前,資料庫(在本例中)正在驗證資料以確保其唯一,如果不是,則丟擲異常。
我的觀點(我承認我說的非常冗長;))是,這都是驗證邏輯,應該放在 Validator 中。 將此唯一性檢查移至 validator 它所屬的地方(!)可以帶來許多好處
注意:有一種論點是您正在重複您的驗證邏輯; 資料庫知道什麼是唯一的,什麼不是唯一的,那麼為什麼在控制器中重複該邏輯? 好吧,關鍵是您正在重複該邏輯,您正在使用引發 DuplicateXXXException 來指示驗證失敗,因此這並不是一個有效的論點。
還有另一種論點是,這不能 100% 保證捕獲所有(在本例中)重複的鍵。 這是真的。 在呼叫驗證之後但在中間層呼叫之前,有一個很小的機會視窗,另一個程序可能會偷偷地建立唯一的行,但這只是一個非常非常小的視窗(通常是毫秒),並且無論如何都可能會丟擲 OptimisticLockingException。 還要考慮資料的性質。 兩個不同的執行緒同時建立一個唯一的實體是不太可能的。 如果確實發生了,那也沒關係。 讓異常傳遞到容器,因為它現在確實是異常情況。
咆哮結束。
附言。我的其餘部落格文章可能同樣冗長:)