Per essere onesto, non sono sicuro se questo è il posto migliore per una domanda come questo. Forse la visione del codice è una soluzione migliore. A parte tutto, IMO, nessuna delle due proposte suggerite è "l'approccio migliore". Ma come sempre, quella potrebbe essere una cosa personale.
Dal mio punto di vista, il modo migliore per andare su OOP è quello di inserire tutti i dati negli oggetti ASAP e implementare un livello di servizio che si occupa delle operazioni che richiedono più query o più oggetti.
Se si presume che si stia utilizzando un pattern MVC-ish, il controller riceve i dati. Qui, si istanzia un oggetto Game
e si imposta l'ID su 123456
. È possibile passare quell'istanza a un metodo di servizio denominato fillGameModel(Game $gameInstance)
. Questo metodo si collega al DB e imposta tutte le altre proprietà dell'oggetto Game
e lo restituisce. Lo stesso vale per l'oggetto User
. Entrambi questi oggetti possono quindi essere passati a un altro metodo di servizio: likeGame(Game $game, User $user)
. Questo metodo può prendersi cura del resto.
Personalmente, farei ancora un passo avanti e usare i mapper per l'accesso al mio DB, ma non ne parlerò ora. Ecco un esempio utilizzando un servizio, e un altro approccio OO:
//controller:
$user = new User();
$user->setId($_SESSION['user_id']);
$game = new Game();
$game->setId(123456);//wherever you get this from
$service = new MainService();
$service->userLikes($game,$user);
//service:
public function userLikes(Game $game, User $user)
{
$user = $this->_completeUser($user);
$game = $this->_completeGame($game);
//insert or update whatever data you need...
}
protected function _completeUser(User $user)
{
$db = $this->_getConnection();//asuming PDO, to keep things simple
$query = 'SELECT * FROM my_db.users WHERE id = ?';
$stmt = $db->prepare($query);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
foreach ($row as $field => $value)
{//this implies getters and setters in your model
$user->{'set'.ucfirst(strtolower($field))}($value);
}
return $user;
}
protected function _completeGame(Game $game)
{
$db = $this->_getConnection();
$query = 'SELECT * FROM my_db.games WHERE id = ?';
$stmt = $db->prepare($query);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
foreach ($row as $field => $value)
{//field id becomes "setId" method, field name "setName" etc...
$game->{'set'.ucfirst(strtolower($field))}($value);
}
return $game;
}
//just for show: a pseudo-overloader method, if your models all share the same
//abstract class.
protected function _completeAny(Model_Abstract $model)
{
$modelName = get_class($model);
if (method_exists($this,'_complete'.$modelName))
{
return $this->{'_complete'.$modelName}($model);
}
throw new Exception('No completion method for '.$modelName.' found');
}
Nuovamente, i loop attraverso il gruppo di risultati potrebbero essere sostituiti da un metodo in una classe modello astratto che prende un array come argomento, e trasforma i fieldnames per i loro setter corrispondenti. Un sacco di spazio per l'astrazione, direi ;-)
fonte
2012-09-18 07:19:34
'È una buona pratica catturare l'id utente attuale nel modello di gioco?' No. 'o dovrei passarlo come parametro?' Sì. Pensaci, adesso memorizzi l'ID dell'utente attivo nella sessione, cosa succede se in seguito lo memorizzi da qualche altra parte? Ancora più importante, la tua funzione è utilizzabile solo per l'utente attivo corrente, non puoi 'like()' per nessun altro utente. L'id utente è una dipendenza esterna, non c'è assolutamente alcun motivo per legare il tuo modello di gioco ad esso, letto su [dipendenza da iniezione] (http://en.wikipedia.org/wiki/Dependency_injection). – yannis