我的大脑开始受到伤害,所以我决定在这里问问。验证入境或保存之前?
我有一个数据对象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