我的大腦開始受到傷害,所以我決定在這裏問問。驗證入境或保存之前?
我有一個數據對象Employee。 Getters,setter,格式化程序等我有一個管理器EmployeeManager,它負責處理數據庫訪問和其他事情。現在我在EmployeeManager中有一個很大的驗證塊,但我一直在想我是否可以將其中的一些移動到setters。
例如,現在我有;
public function getSSN($bFormatted = true) {
return ($bFormatted) ? $this->format_ssn($this->SSN) : $this->SSN;
}
public function setSSN($s, $bValidate = false)
{
// If we're validating user entry, save a copy.
// Either way, store a trimmed version.
if ($bValidate): $this->SSNToValidate = $s; endif;
$this->SSN = str_replace('-', '', $s);
}
public function getSSNToValidate() { return $this->SSNToValidate; }
這樣做是:
*當你設置SSN,如果它被系統(如從數據庫)來完成,然後它setSSN('123456789', false)
,由於社會安全號碼存儲在數據庫SANS破折號。
*當您從用戶輸入設置SSN時,它只是簡單地setSSN('123-45-6789')
然後不僅修剪破折號,而且還存儲原始版本以驗證(因爲我想根據格式進行驗證)
*當您獲得SSN時,如果請求格式化(並且它總是在寫入數據庫時除外),它將根據Employee類中的另一個函數進行格式化。
所以我的問題是:我可以在這裏添加驗證到setter,而不是依靠Manager類中的單片驗證功能?因爲我開始必須處理來自整個應用程序的錯誤,所以我決定暫時轉移到一箇中央的Error Handler靜態類,而不是每個管理者維護它自己的錯誤列表。
的,因爲這一點,我可以很容易地添加錯誤處理到這一點:
public function setSSN($s, $bFromUser = false)
{
if ($bFromUser && !$this->validateSSN($s))
{
ErrorHandler::add(array('ssn' => 'Invalid SSN entered'));
}
else
{
$this->SSN = str_replace('-', '', $s);
}
}
所以我想我的問題是:在所有這是否有道理還是我從管理者移動驗證沖水自己(要在需要時還是在寫入數據庫之前執行)到對象(在輸入時執行)?
這是整體通用的,我只是使用SSN作爲一個很好的例子。
是的,我看到其他人說,保持對象的完整性是至關重要的,這意味着不要在其中存儲流浪數據。如果您嘗試添加bum數據,請拒絕它。雖然我也看到了bum用戶輸入(這是)並不例外,但它是預期的,因此您應該毫無例外地處理它。但我認爲,這是更多的語義和編程實踐,而不是這個問題。 – Andrew 2011-03-31 21:38:38
我同意處理用戶數據會很痛苦。在這種情況下,我通常最終會進行兩次驗證:在UI中一次,所以我可以通知他們這個問題,然後再次在對象中。我覺得確保對象是正確的並且驗證可能被調用兩次比讓我最終存儲不良數據的可能性更安全。 – brainimus 2011-03-31 21:45:21
將這個標記爲答案,因爲我已經去了「永遠不要讓你的對象處於有效狀態」的想法。例如,如果我知道SSN將永遠不會被設置爲無效數字(因爲它在設置上得到驗證),那麼我知道我不一定需要稍後再驗證它。我必須學會信任代碼。 – Andrew 2011-04-06 12:57:23