3
我明白依賴注入的重要性及其在單元測試的作用,這就是爲什麼下面的問題是給我停下來:PHP OOP:避免在領域模型模式辛格爾頓/靜態方法
一個領域,我掙扎不使用單身人士是身份地圖/工作單元模式(它保持對域對象狀態的選項卡)。
//Not actual code, but it should demonstrate the point
class Monitor{//singleton construction omitted for brevity
static $members = array();//keeps record of all objects
static $dirty = array();//keeps record of all modified objects
static $clean = array();//keeps record of all clean objects
}
class Mapper{//queries database, maps values to object fields
public function find($id){
if(isset(Monitor::members[$id]){
return Monitor::members[$id];
}
$values = $this->selectStmt($id);
//field mapping process omitted for brevity
$Object = new Object($values);
Monitor::new[$id]=$Object
return $Object;
}
$User = $UserMapper->find(1);//domain object is registered in Id Map
$User->changePropertyX();//object is marked "dirty" in UoW
// at this point, I can save by passing the Domain Object back to the Mapper
$UserMapper->save($User);//object is marked clean in UoW
//but a nicer API would be something like this
$User->save();
//but if I want to do this - it has to make a call to the mapper/db somehow
$User->getBlogPosts();
//or else have to generate specific collection/object graphing methods in the mapper
$UserPosts = $UserMapper->getBlogPosts();
$User->setPosts($UserPosts);
有關如何處理這種情況的任何建議?
我很討厭將映射器/數據庫訪問的實例傳遞到域對象本身以滿足DI - 同時,避免導致域對象內的大量調用與外部靜態方法有關。
雖然我猜想如果我想要「保存」成爲其行爲的一部分,那麼在其構建中需要這樣做的設施。也許這是一個責任問題,域對象不應該被存儲負擔。這只是Active Record模式的一個很好的功能 - 以某種方式實現它會很好。
當然,我也是這麼做的。問題是這樣的:你是否創建了一個映射器的NEW實例,或者你是否對映射器進行靜態調用(假設用戶映射器必須已經存在,以便有用戶),它存在於用戶之外?因爲如果你調用一個新的映射器,你可能需要調用一個新的DB句柄,再加上對工作單元和ID映射的引用...... - 而外部類已經完成了所有設置 – sunwukung 2010-04-23 16:01:38
我存儲了DB句柄(在我的情況下MDB2)在父映射器類中是靜態的,所以無論映射器有多少實例,它們都共享相同的句柄。 – 2010-04-23 16:49:15
啊,我現在看到,這是一個Monostate類模式不是嗎? – sunwukung 2010-04-24 08:29:45