5

私はフラッシュゲームのウェブサイトに取り組んでいます。ゲームユーザーの2つのモデルと、たとえば「ユーザー1はゲーム3が好き」のようにユーザーのアクションを保持する中間テーブルがあります。

  1. 私のような機能に最適な場所はどこですか?
  2. ゲームモデルで現在のユーザーIDを取得することは良い習慣ですか?または、パラメータとして渡す必要がありますか?

パフォーマンス上の理由から、ゲームテーブルのlikesフィールドもインクリメントします。シンプルにするために、ユーザーがすでにゲームを気に入っているかどうかの確認は省略しました。
これが私のオプションです:

最初のバージョン:

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

2番目のバージョン:

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

1 に答える 1

1

正直なところ、このような質問に最適な場所かどうかはわかりません。おそらく、コードレビューの方が適しています。すべてのことはさておき、IMO、あなたが提案する2つのテイクのどちらも「最良のアプローチ」ではありません。しかし、いつものように、それは個人的なことかもしれません。
私の見解では、OOPを実行する最良の方法は、すべてのデータをオブジェクトにできるだけ早くプッシュし、複数のクエリまたは複数のオブジェクトを必要とする操作を処理するサービスレイヤーを実装することです。

MVC風のパターンを使用していると思われる場合は、コントローラーがデータを受信します。そこで、Gameオブジェクトをインスタンス化し、idをに設定し123456ます。そのインスタンスを。というサービスメソッドに渡すことができますfillGameModel(Game $gameInstance)。このメソッドはDBに接続し、Gameオブジェクトの他のすべてのプロパティを設定して返します。オブジェクトについても同じことが言えUserます。次に、これらのオブジェクトの両方を別のサービスメソッドに渡すことができますlikeGame(Game $game, User $user)。その方法で残りを処理できます。
個人的には、さらに一歩進んでDBアクセスにマッパーを使用しますが、今はそれについては説明しません。これは、サービスを使用した例と、より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');
}

この場合も、結果セットを介したループは、引数として配列を取り、フィールド名を対応するセッターに変換する抽象モデルクラスのメソッドに置き換えることができます。抽象化の余地はたくさんあると思います;-)

于 2012-09-18T07:19:34.733 に答える