2009-05-20 1 views
3

シナリオ1-nリレーショナルマッピングをモデル化するために適切なJavaデータ構造を選択する方法は?

私は可能な限り簡潔になるつもりです。基本的にはclassdiagを参照して、私はSocketManager(1つのソケット接続を管理する)のリストを管理するファサードを持っています。各SocketManagerは、一意のSocketUserIdを使用してリモートサーバーにログインします。さらに、それぞれSocketManagerは、受信者の特定のリスト宛のクライアントからのメッセージを受け入れます。説明のために、受信者は、名前で識別されるリモートデータバケットと同じように考えてください。

クライアントは、このようなデータを送信する。

SocketFacade facade = ...; 

byte[] data = ... 

facade.sendData(receipient, data); 

場合SocketFacade開始は、SocketUserIdReceipients間の1-Mの関係を返すMySQLのテーブルを照会します。私はMultiValuedMapを使用して、この1-m関係を表します。複数のSocketManagerは、マップを反復処理することで開始されます。

(1) Map< SocketUserId, List<Receipient> > 

私たちは、それぞれSocketUserIdの "アリス" & "トム" と2 SocketManager秒を持っていると仮定し

  +----SocketManager1 ("alice") for Receipients { "B", "C" } 
      | 
SocketFacade 
      | 
      +----SocketManager2 ("tom") for Receipients { "A", "D" } 

質問私はのsendDataメソッドを実装する方法のように結合しています

。基本的には、受信者(例:「B」)から責任者(、SocketManager)にマッピングする方法が必要です(例:SocketManager1)。

だが、私はこの

(2) Map< SocketUserId, SocketManager > 
(3) Map< Receipient, SocketUserId > 
  • を行うとしましょう、私は(2)の値のためにSoftReferenceが必要でしょうか?
  • 受信者から直接にマップする必要があります。SocketManager
  • SocketFacadeは、(1)で表される関係を変更する方法もサポートしています。データベースに書き込むと、(1)、(2)、&(3)のメモリ内データ構造が同期して変更する必要があります。 SocketFacadeもスレッドセーフでなければなりません。最初のアイデアは、DBへの追加/削除によって変更がコールバックを介して伝播するような、ある種のパブリッシュ・サブスクライブ・システムを持つことです。

    interface Callback 
    { 
        void receipientAdded(Receipient r); 
        void receipientDeleted(Receipient r); 
    } 
    
+1

「受信者」ではなく「受信者」です。コードのスペルミスはバグの厄介な原因です。 – Svante

+0

OK。ありがとう。私の悪い。 – ashitaka

答えて

1

ReceipientSocketManagerを参照してください。そうすれば、マップを避けることができます(RAMが増え、遅くなり、値を追加しません)。

SocketManagerには、Receipientのリストを保管してください。 Receipientを追加して削除するときに、ポインタをSocketManagerに更新します。

SocketFacadeには、SocketUserIdが、SocketManagerを返すマップが必要です。そのマップは、マップ内のIDを照会することで満たされます。すべての管理者が存在する場合は、それぞれに受信者を追加します。これには2つのSQLクエリが必要です。

これは、どのORMツールでも簡単にマッピングできます。

+1

私の意見では、SocketManagerを受信者に入れるのはあまり良いことではありません。次に、受信者はSocketManagerをSocketFacadeのクライアント/呼び出し側に公開します。その背後にある質問は、 "受信者は、どのSocketManagerが彼の責任であるかを知る必要がありますか"。このシナリオをどのように理解しているので、これは望ましくなく、ファサードの後ろに隠されるべきです。ファサードのセットアップの問題です。これまで私はこの権利を得ていますか? – rudolfson

+0

基本的に、SocketFacade#sendData(..)に供給されたメッセージを正しいSocketManagerにディスパッチしたいと思います。それだけです。受信者は文字列識別子で識別されます。もう1つの設計基準は、特定のSocketManagerによって処理される受信者を追加および削除できることです(これにはメモリ内の変更とデータベースの更新が含まれます)。あなたの質問に答えるために、受信者は理想的にはそれが関係するSocketManagerについて知る必要はありません。 – ashitaka

+0

@rudolfson:ああ、私は誤解しました。私はこれが "SocketManagerのすべての受信者にメッセージを送る"のようだと思った。 Hm。ふりだしに戻る。 –

1

SocketUserIdとSocketManagerの間に1-1の関係があるため、SocketManangerのSocketUserIdへの参照と受信者のSocketManagerへの参照を追加することはできません。

次に、受信者を含むマップとSocketManagerのリストがファサードにあります。 sendData関数では、受信者をマップから取得し、この受信者からそのSocketManagerへの参照を取得します。抽象的なレベルで

についてギヨーム

+0

私は最初に地図の中にSocketManagerを張っておくことを心配しました。なぜなら、その下には2つのスレッドとソケットチャンネルがあるからです。 List を保持することを計画していますので、シャットダウンを呼び出すと便利です。どう思いますか ?はいSocketManagerはSocketUserId(1-1)への参照を持ちます。 1人の受信者が1つのSocketManagerだけに関連するので、なぜSocketManagerのリストが必要でしょうか?あなたの考えから、私はMap だけを持っています。私はあなたを正しく理解していますか? – ashitaka

+1

@ashitaka:ハァッか。あなたの例から、SocketManagerは1:Nです! –

+0

@AaronDigulla私は間違いを犯しました。私は、 "1つのSocketUserIdが1つのSocketManagerだけに関連しているので..."と言っていました。受信者へのSocketManagerは1:N – ashitaka

1

は、あなたが持っている:nは OtherThing Sに関連する1 ThingThingを参照し、 OtherThingへの参照の java.util.List<OtherThing>を含む特別な関係オブジェクトを作成することによってこれをモデル化することができます。これにより、あなたのドメインオブジェクト(物)が関係情報で整然としたままになります。しかし、正しいと思われる場合は、 java.util.Listをクラス Thing(またはサブクラス)に直接追加する方が簡単です。関係を確立する必要がある場合にのみ、List変数をnullのままにして java.util.ArrayList<OtherThing>で入力することができます。

関連する問題