注意力!
在过去的一个月里,我对这个主题的看法发生了一些变化。虽然答案 where 仍然有效,但在处理大型对象图时,我建议改用 Unit-of-Work 模式。您可以在此答案中找到它的简要说明
我有点困惑what-you-call-Model与ORM 的关系。这有点令人困惑。特别是因为在 MVC 中,模型是一个层(至少,我是这么理解的,而且你的“模型”似乎更像是 域对象)。
我将假设您拥有的是如下所示的代码:
$model = new SomeModel;
$mapper = $ormFactory->build('something');
$model->setId( 1337 );
$mapper->pull( $model );
$model->setPayload('cogito ergo sum');
$mapper->push( $model );
而且,我将假设what-you-call-Model有两种方法,设计器供数据映射器使用:getParameters()
和setParameters()
. 并且您isDirty()
在 mapper 存储what-you-call-Model的状态和调用之前调用cleanState()
- 当 mapper 将数据拉入what-you-call-Model时。
顺便说一句,如果您有更好的建议来获取数据映射器的值而不是setParameters()
and getParameters()
,请分享,因为我一直在努力想出更好的东西。在我看来,这就像封装泄漏。
这将使数据映射器方法看起来像:
public function pull( Parametrized $object )
{
if ( !$object->isDirty() )
{
// there were NO conditions set on clean object
// or the values have not changed since last pull
return false; // or maybe throw exception
}
$data = // do stuff which read information from storage
$object->setParameters( $data );
$object->cleanState();
return $true; // or leave out ,if alternative as exception
}
public static function push( Parametrized $object )
{
if ( !$object->isDirty() )
{
// there is nothing to save, go away
return false; // or maybe throw exception
}
$data = $object->getParameters();
// save values in storage
$object->cleanState();
return $true; // or leave out ,if alternative as exception
}
代码片段Parametrized
中是接口的名称,应该实现哪个对象。在这种情况下,方法getParameters()
和setParameters()
。它有一个奇怪的名字,因为在 OOP 中,这个implements
词的意思是has-abilities-of,而extends
意思是 is-a。
到目前为止,您应该已经拥有类似的所有内容...
现在这里是isDirty()
andcleanState()
方法应该做的:
public function cleanState()
{
$this->is_dirty = false;
$temp = get_object_vars($this);
unset( $temp['variableChecksum'] );
// checksum should not be part of itself
$this->variableChecksum = md5( serialize( $temp ) );
}
public function isDirty()
{
if ( $this->is_dirty === true )
{
return true;
}
$previous = $this->variableChecksum;
$temp = get_object_vars($this);
unset( $temp['variableChecksum'] );
// checksum should not be part of itself
$this->variableChecksum = md5( serialize( $temp ) );
return $previous !== $this->variableChecksum;
}