2009-10-16 26 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