2009-10-16 6 views
0

Exemple:objet modifié après l'état de l'objet ou le stockage utilisé

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

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

si j'ajouter un utilisateur au stockage de l'utilisateur, puis modifier cet objet utilisateur? Dans ce cas, vous pourriez argumenter que les objets utilisateur seulement devraient être stockés sur __destruct. Mais parfois ce n'est pas une option (par exemple, imaginez que l'utilisateur est affiché et mis à jour par la suite).

Répondre

1

Les écritures implicites dans la base de données sont probablement une mauvaise idée. Cela devrait être une opération explicite et contrôlée.

Votre modèle est un peu bizarre pour moi, mais je pense que ce que vous voudriez faire

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(); 
} 

Mais Personnellement, je ne suis pas fou de cette conception de classe. Il y a quelques modèles bien établis pour cela qui sont moins déroutants, tels que ActiveRecord.

+0

Je ne suis pas un grand fan de l'enregistrement actif. Mais il a probablement l'avantage ici que $ object-> save() enregistre clairement l'état à un moment donné (par exemple, le code client sait ce qu'il a fait avec). Bien que l'inconvénient est peut-être aussi que lorsque plusieurs éléments de code travaillent avec $ object, il n'est pas clair qui est responsable du déclenchement de save(). – koen

+0

ActiveRecord n'est pas le seul motif. ZF utilise (Data/Row) Data Gateway, par exemple. –

+0

Je pense qu'il a le même problème. Le modèle va cacher la passerelle. – koen

1

Je suis d'accord avec Peter, le modèle ci-dessus me semble un peu bizarre et je recommande de ne pas sauvegarder implicitement dans le datastore.

En outre, un modèle à utiliser est quelque chose comme:

class UserStorage { 
    $_user; 

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

Donc, si vous avez plusieurs mises à jour d'un objet utilisateur dans l'exécution de votre application PHP, vous pouvez utiliser

addUser(user,false) 

tous le chemin jusqu'au dernier appel à

addUser(user) 

Cela permettra d'alléger le besoin de multiples insère/met à jour la base de données.

Cependant, votre problème d'emplacement de l'application pour décider de sauvegarder définitivement en db reste, et concerne plus le flux logique que la représentation d'objet. Il peut être utile d'avoir une fonction end() dans le script qui conserve tous vos objets dans la base de données.

+0

En fait, je ne comprends pas pourquoi c'est implicite. Le code client crée un objet utilisateur et l'ajoute au magasin de l'utilisateur. – koen

+0

Il est implicite en ce sens que l'objet de stockage n'est pas enregistré explicitement par d'autres objets qui l'utilisent, c'est-à-dire si vous choisissez d'enregistrer dans db dans votre méthode __destruct. Si vous continuez à utiliser addUser() dans votre code, il est explicite et ne vous inquiétez pas. – Pras

Questions connexes