2011-02-07 12 views
0

私はOO/DBの関係に何をすべきかについてのビットたくさんいます...ここでシングル参照

は、DBモデルである:

CREATE TABLE User 
    Id 

CREATE TABLE Location 
    userId 
    // EDIT oups, wrong ! 
    // placeId 
    // Should be : 
    seatId 

CREATE TABLE Game 
    locationId 

現在、いくつかのコード:

class User 
{ 
    private Location locations[]; // need this for several reasons... 

    public function loadFromDatabase() 
    { 
     // Load data from DB 
     // ... 
     result = DB::query("SELECT Id FROM Locations WHERE userId="+this->Id); 
     foreach(result) 
     { 
      l = new Location(); 
      l->loadFromDatabase(result); 
      locations[] = l; 
     } 
    }  
} 

class Location 
{ 
    private User user; 
    public function loadFromDatabase() 
    { 
     ... 
    } 
} 

class Game 
{ 
    private Location location; 
    public loadFromDatabase() 
    { 
     /* 
     Here comes the problem : 
     how to have a reference to a location 
     created by the User class ? 
     */ 
    } 
} 

ユーザーは複数の場所でゲームをプレイします。 EDIT:そして、各場所でユーザーが座席上で演奏します。または別の座席に... ゲームがどこで行われたか知りたいときは、Game.locationにアクセスします。誰がそれをプレイしたのか知りたければ、Game.location.userにアクセスします。

ここに私の問題があります:私はGame.locationをUser.locationsのいずれかと同じ参照にしたいと思います。これを行うには... 世界的に、私は自分のコードについて何か間違っていると感じます...

助けが必要ですか?あなたはLocation表にplaceIdを持っているので おかげ

答えて

1

は、私はLocationテーブルは、単にユーザと場所との間に多対多マッピングを表している場所は、実際に、何であるかを説明しPlaceテーブルがあると仮定します。

この場合、Locationは、Idを持つ必要はなく、クラスである必要はありませんが、Placeはあります。

データベースから各オブジェクトのインスタンスを1つだけロードするには、インスタンスを各クラスの静的マップにキャッシュします。

class Place 
{ 
    // Static 
    private static Place loadedPlaces[]; 

    public static function get(id) 
    { 
     if (!loadedPlaces[id]) 
     { 
      loadedPlaces[id] = new Place(id); 
      loadedPlaces[id]->loadFromDatabase(); 
     } 
     return loadedPlaces[id]; 
    } 

    // Non-static 
    private id; 

    public function loadFromDatabase() 
    { 
     // ... 
    } 
} 

次に、ユーザーまたはゲームのプロパティの場所への参照を取得するには、静的メソッドを使用してアクセスします。

class User 
{ 
    public function loadFromDatabase() 
    { 
     result = DB::query("SELECT placeId FROM Locations WHERE userId="+this->Id); 
     foreach(result) 
     { 
      places[] = Place::get(result); 
     } 
    }  
} 

class Game 
{ 
    public function loadFromDatabase() 
    { 
     place = Place::get(place); 
    } 
} 

これは使用しています:

  • Lazy initializationを、必要なときの場所にのみロードされるため。
  • Multiton pattern idごとに1つのインスタンスしか存在しないためです。
  • あまりにもfactory methodではありません。なぜなら、オブジェクト階層が含まれていないからです。
+1

ありがとうございました。あなたは私に必要なものをくれました。私はいくつかの詳細を与えなかったし、私はクラス名を正しく書いていなかった。 placeIdの代わりに、seatIdを読んでください。ユーザは、1つの指定された座席の場所でゲームを行い、別の指定座席の同じ場所で遊ぶことができる。しかし、あなたが静的マップについて説明したことは、まさに私が必要としていたものです。つまり、独自のインスタンスを保存することができます。ところで、このようなデザインパターンはありますか? – Antoine

+0

いくつかのリンクを追加しました。 ゲーム/位置関係に関して、それは1対1のように聞こえるので、2つのものを分ける必要はないかもしれません。代わりに 'game_id'、' user_id'と 'place_number'を持つテーブルを使って、ゲームをユーザとそのプレイス番号に関連させ、' Game'オブジェクトの(固定サイズ?)配列をユーザにリンクさせることができます。 – aaz

+0

リンクをありがとう、それは私が必要としたものです。ほとんどの場合、私は自分の問題に対する解決策を持っていますが、私はそれらが「うまくコード化されている」ことは決して確かではありません。そのため、私はデザインパターンに基づいてコードを書くことが大好きです。そしてあなたの説明+リンクは仕事をする! – Antoine