2012-09-18 61 views
5

我正在研究一個Flash遊戲網站。我有兩個模型:遊戲用戶和一箇中間表,其中我保留用戶的行爲,例如:「用戶1喜歡遊戲3」。「喜歡」功能的最佳做法

  1. 哪裏是我最喜歡的功能?
  2. 這是一個很好的做法,抓取當前用戶ID在遊戲模型?還是應該將它作爲參數傳遞?

由於性能方面的原因,我也增加了遊戲表中的喜歡字段。 我省略了檢查用戶是否已經喜歡遊戲,只是爲了保持簡單。
這裏是我的選擇:

第一個版本:

$user->like(12345); 

class User 
{ 
    public function like($game_id) 
    { 
    $like = new User_Game(); 
    $like->user_id = $this->id; 
    $like->game_id = $game_id; 
    $like->save(); 

    $obj = new Game($game_id); 
    $obj->likes++; 
    $obj->save(); 
    } 
} 

第二個版本:

$game->like(); // by current user 

class Game 
{ 
    public function like() 
    { 

    $like = new User_Game();  
    $like->user_id = $_SESSION[‘user_id’];  
    $like->game_id = $this->id;  
    $like->save(); 

    $this->likes++;  
    $this->save();  
    }  
}  
+0

'在Game Model中抓取當前用戶標識是否是一個好習慣?'否'或者我應該將它作爲參數傳遞嗎?想一想,現在你將活動用戶的ID存儲在會話中,如果稍後將其存儲在其他地方,會發生什麼?更重要的是,你的功能只適用於當前活動的用戶,你不能「喜歡()」任何其他用戶。用戶ID是一個外部依賴項,絕對沒有理由將你的遊戲模型綁定到它,閱讀[依賴注入](http://en.wikipedia.org/wiki/Dependency_injection)。 – yannis

回答

1

老實說,我不知道如果這是一個問題的最佳場所如此。也許codereview更適合。除了所有的事情,國際海事組織,這兩個建議你都不是「最好的辦法」。但一如既往,這可能是個人的事情。
在我看來,關於OOP的最好方法是儘快推送對象中的所有數據,並實現一個服務層來處理需要多個查詢或多個對象的操作。

如果我可能認爲您使用的是MVC-ish模式,那麼您的控制器會收到這些數據。在那裏,您實例化一個Game對象,並將該ID設置爲123456。您可以將該實例傳遞給名爲fillGameModel(Game $gameInstance)的服務方法。此方法連接到數據庫,並設置Game對象的所有其他屬性並將其返回。 User對象也一樣。這兩個對象都可以傳遞給另一個服務方法:likeGame(Game $game, User $user)。該方法可以處理其餘的事情。
就我個人而言,我會更進一步,並使用映射器來訪問我的數據庫,但我現在還沒有進入。下面是一個使用的服務的示例,並且更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'); 
} 

同樣,通過結果集的環可以與該需要的陣列作爲參數,並轉換字段名到的抽象模型類中的方法來代替他們相應的制定者。有足夠的抽象空間,我會說;-)