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