存储或使用对象状态后更改对象

时间:2009-10-16 19:50:32

标签: php oop object state

示例:

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

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

如果我将用户添加到用户存储并稍后更改该用户对象,该怎么办?在这种情况下,您可能会认为用户对象只应存储在__destruct上。但有时这不是一个选项(例如,想象用户之后会显示和更新)。

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:1)

我同意Peter的意见,上面的模型对我来说似乎有点古怪,我建议不要隐式保存到数据存储区。

此外,使用的模式类似于:

class UserStorage {
   $_user;

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

因此,如果在执行PHP应用程序时有多个User对象更新,则可以使用

addUser(user,false) 

一直到最后一次调用

addUser(user)

这将减少对DB的多次插入/更新的需要。

但是,您在应用程序中决定最终保存到db的位置的问题仍然存在,并且更多地是关于逻辑流而不是对象表示。在脚本中使用end()函数可能会有所帮助,该函数将所有对象持久保存到db。