I'll use an abstract (and simple) example to illustrate the question: CarDomainObject
, as follows: (example mysql data types are listed beside the members)
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;
}
}
Say that we want to insert a new car into the database, so we set some values:
$carDomainObject->setData(array('make' => 'ford', 'model' => 'taurus'));
Now the values that aren't set will still be NULL
, which works well for the isDirty()
method. What this schema doesn't work for is when inserting an object (that's been initialized like above, with only certain values) into the database, where NULL
might not be a valid value for the column.
So, my question is: How can we validate that each of the data pieces within the domain object is ready for DB insertion? The way I see it there's a few options:
If we use default values for the member variables (
0
for an int,''
for a varchar, etc), thenisDirty()
becomes more complex, because a null check wouldn't be sufficient. However, checking that the data is able to be inserted becomes trivial because the default values could be inserted without issueIf we stick with
NULL
as the default values, thenisDirty()
stays fairly trivial, but ensuring the data is ready for the DB becomes complex.Validate each variable individually, which would get ugly very quickly depending on the DO.
Use default values within MySQL - Not really an option for me, but a valid option in general
You seem to be trying to determine, if model is valid, before it gets saved. But your structure is flawed:
If you using single setter, then this setter will grow in complexity as you try to add more and more conditions. Also, by avoiding separate setter for each parameter, you loose the ability to actually validate the parameters.
When you set invalid value to domain object, it should create internal error state.
Your validation assumes, that all values must be not-null. What if they can be
NULL
? Validation of parameters should check, if values confirm with business rules, not with constraints set by database.When mapper tries to store invalid values in the database, it will cause an error. If you are using properly set up PDO instance, it will rise an exception. How you handle that exception, then is your choice. Domain objects are not responsible for data integrity in database.