我将使用一个抽象(和简单)示例来说明问题:CarDomainObject
,如下所示:(成员旁边列出了示例mysql数据类型)
class carDomainObject extends DomainObjectAbstract {
public $uid; //int
public $make; //varchar
public $model; //varchar
public $productionDate; //timestamp
public $doors; //tinyint
}
class DomainObjectAbstract {
public function setData(array $data=array())
{
foreach ($data as $key => $value)
{
if ( ! empty($key))
{
$this->$key = $value;
}
}
}
//if $val is not passed, checks for ANY set value,
// else checks that $this->$val is set (dirty)
public function isDirty($val=false)
{
foreach(get_object_vars($this) as $key => $property)
{
if( ! is_null($property) && ( ! $val || $key == $val))
{
return true;
}
}
return false;
}
}
假设我们想要将新车插入数据库,因此我们设置了一些值:
$carDomainObject->setData(array('make' => 'ford', 'model' => 'taurus'));
现在,未设置的值仍为NULL
,适用于isDirty()
方法。这个模式不起作用的是将一个对象(如上所述初始化,只有某些值)插入到数据库中,其中NULL
可能不是该列的有效值。
所以,我的问题是:我们如何验证域对象中的每个数据块是否已准备好插入数据库?我看到的方式有几个选择:
如果我们使用成员变量的默认值(0
表示int,''
表示varchar等),那么isDirty()
会变得更复杂,因为null检查是不够的。但是,检查数据是否能够插入变得微不足道,因为可以插入默认值而不会出现问题
如果我们坚持使用NULL
作为默认值,那么isDirty()
保持相当简单,但确保数据为数据库做好准备会变得复杂。
单独验证每个变量,根据DO的不同,这会很快变得难看。
在MySQL中使用默认值 - 对我来说不是一个真正的选项,但通常是一个有效的选项
答案 0 :(得分:0)
我觉得你接受了this post的部分内容,但误解了问题,那就解决了。
在保存之前,您似乎试图确定模型是否有效。但是你的结构存在缺陷:
如果您使用单一设置器,那么当您尝试添加越来越多的条件时,此设置器的复杂性会增加。此外,通过避免为每个参数单独设置,您将失去实际验证参数的能力。
当您为域对象设置无效值时,它应该创建内部错误状态。
您的验证假设所有值必须不为null。如果他们可以NULL
怎么办?如果值通过业务规则确认,则应检查参数的验证,而不是使用数据库设置的约束。
当mapper尝试在数据库中存储无效值时,会导致错误。如果您使用正确设置PDO实例,它将引发异常。您如何处理该异常,那么这是您的选择。域对象不负责数据库中的数据完整性。