2009-10-16 25 views
0

實施例:改變的對象之後存儲或對象的狀態下使用

class UserStorage { 
    public function addUser(User $user) { //saves to db } 
} 

class User { 
    public function setName($name); 
} 

如果我用戶添加到用戶的存儲和以後更改用戶對象?在這種情況下,您可能會爭辯說,用戶對象只應存儲在__destruct上。但有時這不是一種選擇(例如,想象用戶在之後顯示和更新)。

回答

1

隱式寫入數據庫可能是一個壞主意。這應該是一個明確的,受控的操作。

你的模式是有點怪我,但我認爲這你要怎麼辦呢

class UserStorage 
{ 
    const ACTION_INSERT = 'INSERT'; 
    const ACTION_UPDATE = 'UDPATE'; 

    public function addUser(User $user) 
    { 
     $this->saveUser($user, self::ACTION_INSERT); 
    } 

    public function updateUser(User $user) 
    { 
     $this->saveUser($user, self::ACTION_UPDATE); 
    } 

    protected function saveUser(User $user, $action) 
    { 
     switch ($action) { 
      case self::ACTION_INSERT: 
       // INSERT query 
       break; 
      case self::ACTION_UPDATE: 
       // UPDATE query 
       break; 
      default: 
       throw new Exception('Unsupported action'); 
     } 
    } 
} 

class User 
{ 
    public function setName($name) 
    { 
     // whatever 
    } 
} 

$userStorage = new UserStorage(); 
$user = new User(); 

$userStorage->addUser($user); 

$user->setName('Peter'); 

try { 
    $userStorage->updateUser($user); 
} catch (Exception $e) { 
    echo "There was an error saving this user: " . $e->getMessage(); 
} 

但我個人不是瘋了關於這個類的設計。有一些很好的模式可以減少混淆,例如ActiveRecord

+0

我不是活躍記錄的忠實粉絲。但是它可能具有這樣的優點:$ object-> save()明確地保存了特定時刻的狀態(例如,客戶端代碼知道它做了什麼)。雖然也有一個缺點,那就是當有多塊代碼與$對象一起工作時,不清楚是誰負責觸發save()。 – koen 2009-10-16 20:38:19

+0

ActiveRecord不是唯一的模式。例如,ZF使用(表格/行)數據網關。 – 2009-10-16 20:52:38

+0

我認爲它有同樣的問題。該模型將隱藏網關。 – koen 2009-10-17 10:23:22

1

我同意彼得,上面的模型似乎有點古怪我,我會建議不要隱式保存到數據存儲。

此外,使用模式是這樣的:

class UserStorage { 
    $_user; 

    function addUser(User user, commit = true) { 
     if (commit) { 
     // save to db 
     } else { 
     // populate your internal instance 
     $_user = user; 
     } 
    } 
} 

所以,如果你在你的PHP應用程序的執行用戶對象的多次更新,你可以使用

addUser(user,false) 

所有直到最後一次致電

addUser(user) 

這將減輕對多個插入/更新到數據庫。

但是,您在應用程序中決定最終保存到數據庫的位置的問題仍然存在,並且更多地是關於邏輯流而不是對象表示。在腳本中有一個end()函數可以幫助你將所有對象保存到數據庫中。

+0

我其實不明白爲什麼它是隱含的。客戶端代碼創建一個用戶對象並將其添加到用戶存儲中。 – koen 2009-10-17 10:21:54

+0

這意味着存儲對象不會被其他使用它的對象顯式保存,即如果您選擇在__destruct方法中保存到數據庫。如果你繼續在你的代碼中使用addUser(),這是明確的,不用擔心。 – Pras 2009-10-18 00:23:35