Die*_*ego 5 php oop model-view-controller orm
我不希望任何人说"你不应该重新发明轮子,使用开源ORM" ; 我有一个立即的要求,不能切换.
我正在做一些支持缓存的ORM.即使不支持缓存,我仍然需要此功能,以便知道何时将对象写入存储.模式是DataMapper.
这是我的方法:
我有一个名为AbstractModel
所有模型继承的抽象类.它有一个isDirty()
名为is_dirty的私有(也可以保护,如果需要)的属性调用的公共方法.它必须返回true或false,具体取决于对象数据是否有更改,因为它已加载.
问题是:有没有办法"is_dirty"
在每个setter中编译内部标志而不编码$this->is_dirty = true
?我的意思是:$this->attr = $value
除了业务逻辑需要更改代码之外,我希望大多数时间都有setter .
其他限制是我不能依赖,__set
因为在具体的模型类中,属性已经作为私有存在,因此__set
永远不会在setter上调用.
有任何想法吗?其他ORM的代码示例被接受.
我的一个想法是修改NetBeans setters模板,但我认为应该有一种方法可以在不依赖IDE的情况下执行此操作.
我的另一个想法是创建setter,然后用下划线或其他东西更改private属性的名称.这样setter会调用__set
并在那里处理一些代码来处理"is_dirty"
标志,但是这会破坏POPO概念,而且很难看.
Attantion!
我对这个问题的看法在过去一个月有所改变.虽然答案仍然有效,但在处理大型对象图时,我建议使用工作单元模式.你可以在这个问题中找到它的简要说明
我有点困惑你怎么称呼模型与ORM有关.这有点令人困惑.特别是因为在MVC中,模型是一个层(至少,这就是我理解它,你的"模型"在我看来更像是 Domain Objects).
我假设你拥有的是一个看起来像这样的代码:
$model = new SomeModel;
$mapper = $ormFactory->build('something');
$model->setId( 1337 );
$mapper->pull( $model );
$model->setPayload('cogito ergo sum');
$mapper->push( $model );
Run Code Online (Sandbox Code Playgroud)
并且,我将假设你所谓的模型有两种方法,设计者可供数据映射器使用:getParameters()
和setParameters()
.并且你isDirty()
在mapper存储之前调用你调用的模型的状态和调用cleanState()
- 当mapper将数据拉入你调用的模型时.
顺便说一句,如果你有更好的建议从数据映射器获取值而不是
setParameters()
和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
}
Run Code Online (Sandbox Code Playgroud)
在代码片段中
Parametrized
是接口的名称,该对象应该实现.在这种情况下的方法getParameters()
和setParameters()
.它有一个如此奇怪的名字,因为在OOP中,这个implements
词意味着有能力,而extends
手段是-a.
到目前为止,您应该已经拥有了类似的一切......
现在这是isDirty()
和cleanState()
方法应该做的:
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;
}
Run Code Online (Sandbox Code Playgroud)