簡體   English   中英

何時進行輸入驗證的最佳實踐是什么?

[英]What is the best practice for when to do input validation?

我正在處理一個涉及兩個類的 Java 項目。 一個是項目的驅動程序,另一個是程序的實際功能。 驅動程序將從用戶那里收集輸入,這些值將用於創建另一個類的實例。 另一個類對數據可以是什么有限制(即一個值需要低於某個數字),我想知道什么時候應該驗證輸入是否滿足這些要求。 一般來說,輸入驗證是每個被實例化的類所擔心的,或者是收集數據的類應該做的事情。

提前致謝。

與任何事情一樣,“這取決於”。

我們不要考慮整個應用程序,而是考慮單個組件。 現在我們將它們稱為ApplicationHostBusinessLogic

BusinessLogic組件本身應該是功能齊全的,並且可以被任何應用程序使用。 因此,如果它對其輸入有假設或要求,則需要強制執行這些假設或要求。 例如,如果您要設置一個int值並且該值必須為正數,則 setter 應該強制執行該值。 像這樣簡單的事情:

public void setSomeValue(int someValue) {
    if (someValue <= 0) {
        throw new NumberFormatException("Some Value must be a positive value.");
    }
    this.someValue = someValue;
}

這個想法是BusinessLogic責任強制執行此約束。 任何在違反此約束時嘗試使用BusinessLogic消費代碼都會出錯。 BusinessLogic本身只是宣傳其約束是什么,並要求遵循這些約束。 它不太關心用戶體驗,只關心系統狀態。 如果狀態無效,請快速而大聲地失敗。

那么ApplicationHost應該有同樣的約束嗎? 您可能會問的問題是,是否應該在ApplicationHost重復相同的if語句

這取決於。

請記住,“代碼重復”不是對相同擊鍵的衡量。 它是對相同意圖和責任的衡量。 ApplicationHost不負責維護業務邏輯。 但是,它可能有責任提供良好的用戶體驗。 在這樣做時,它有幾個選擇:

  1. 直接向業務邏輯發送輸入,捕獲並處理任何異常,向用戶顯示友好錯誤。
  2. 在調用業務邏輯之前自行驗證輸入,直接與用戶交互以首先驅動該輸入,並且僅當它有效時才實際執行業務操作。

第一個選項意味着更少的代碼,應用層主要是到業務層的傳遞。 然而,這也意味着在可能存在多個輸入約束違規的情況下,只有第一個遇到的會產生錯誤。 在單獨糾正每個違規行為之前,不會發現剩余的違規行為。

第二個選項意味着“復制”代碼。 然而,它也傾向於產生更好的用戶體驗,應用層和業務層之間的“來回”更少。 (想象一下網站上的一個表單,您有 5 個錯誤,並且必須提交並更正該表單 5 次,因為它一次只能告訴您一個錯誤。)

哪個更好? 這取決於您在應用程序中執行的操作以及所需的整體體驗。 沒有普遍的規則。


但是代碼重復怎么會是一件好事呢? 好吧,它不是。 不是天生的。 在許多情況下,這不是問題。 事實上,您可能會發現,在許多情況下,兩個獨立層中的驗證邏輯實際上並不是完全相同的邏輯。 它們針對不同的目的進行驗證,並且根據應用程序在業務邏輯上的傳遞層與轉換層的數量,它們甚至可能驗證不同的數據“形狀”。

但是,如果它們導致基本相同的驗證邏輯。 然后你可以從中提取第三個“責任”,它可以轉移到它自己的類中。 如果您願意,可以使用BusinessLogicInputValidator 這可以存在於業務邏輯層中,甚至在足夠簡單的情況下也可以存在於BusinessLogic對象中。 並且它將公開BusinessLogicApplicationHost使用的相同操作。

在這種情況下,其執行驗證代碼將被集中,並且,其消耗的是驗證邏輯代碼將被復制。 沒關系,因為使用邏輯的代碼本身並不是邏輯元素,並且不會真正受到相同的“代碼重復”恐懼的影響。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM