我陷入两难境地。我使用DI(读取:工厂)为自制ORM提供核心组件。 容器根据请求提供数据库连接,DAO,Mappers及其生成的域对象。
以下是Mappers和Domain Object类的基本概要
class Mapper{
public function __constructor($DAO){
$this->DAO = $DAO;
}
public function load($id){
if(isset(Monitor::members[$id]){
return Monitor::members[$id];
$values = $this->DAO->selectStmt($id);
//field mapping process omitted for brevity
$Object = new Object($values);
return $Object;
}
}
class User(){
public function setName($string){
$this->name = $string;
//mark modified by means fair or foul
}
}
ORM还包含一个基于工作单元模式的类(Monitor),即
class Monitor(){
private static array modified;
private static array dirty;
public function markClean($class);
public function markModified($class);
}
ORM类本身只是协调从DI容器中提取的资源。因此,要实例化一个新的User对象:
$Container = new DI_Container;
$ORM = new ORM($Container);
$User = $ORM->load('user',1);
//at this point the container instantiates a mapper class
//and passes a database connection to it via the constructor
//the mapper then takes the second argument and loads the user with that id
$User->setName('Rumpelstiltskin');//at this point, User must mark itself as "modified"
我的问题是这个。当用户在Domain Object类上设置值时,我需要在Monitor类中将该类标记为“脏”。我有三个选项之一,我可以看到它
1:将Monitor类的实例传递给Domain Object。我注意到这在FirePHP中被标记为递归 - 即 $这 - >监视器 - > markModified($此)
2:直接在域对象中实例化监视器 - 这会破坏DI吗? 3:使Monitor方法保持静态,并从域对象内部调用它们 - 这会破坏DI也不是吗?
你推荐的行动方案是什么(除了使用现有的ORM,我这样做是为了好玩......)
答案 0 :(得分:1)
好的,我明白了。那怎么样:
$user = new User;
$monitoredUser = new Monitor( $user );
//at update in class Monitor:
Monitor::markDirty( $this );
现在您将Monitor用作装饰器;它在用户对象或处理传入请求的任何其他对象周围添加了一个shell。如果一个对象得到更新,它将被监视器标记为脏,但是因为Monitor使用静态方法,所以它保持在当前类范围内,从而避免了递归。
答案 1 :(得分:0)
以为我从来没有这样做,你的Monitor类似乎对应于“观察者”设计模式。这样您就不必要求Monitor类将类标记为脏,但它应该单独执行。
正如我所说,我从来没有在PHP中做到这一点,但我非常有信心你可以在谷歌上看一种在PHP中实现这种设计模式的方法。
答案 2 :(得分:0)
很大的问题是; markModified()中发生了什么?我复制到代码并尝试了,但我没有收到您报告的错误。所以我猜想丢失了一块拼图?