7

プロジェクト用に独自のシステムを構築しているときに、デザイン パターンについて多くのことを学んでいます。そして、答えが見つからないデザインの問題についてお聞きしたいと思います。

現在、ソケットを使用して複数のクライアントを持つ小さなチャットサーバーを構築しています。現在、次の 3 つのクラスがあります。

  1. ニックネーム、年齢、ルーム オブジェクトなどの情報を保持する人物クラス。
  2. ルーム名、トピック、現在そのルームにいる人物のリストなどの情報を保持するルームクラス。
  3. サーバー上の人物のリストと部屋のリストを持つホテルクラス。

私はそれを説明するために図を作りました:

ホテルクラスのサーバー上に人のリストがあります。これは、現在オンラインになっている人の数を追跡するのに適しているためです (すべての部屋を反復処理する必要はありません)。部屋を検索せずに特定の人を検索できるようにしたいので、人はホテルクラスに住んでいます。

これはデザインが悪いのでしょうか?それを達成する別の方法はありますか?

ありがとう。

4

4 に答える 4

9

私はそれが気に入りません。ホテルには部屋があり、部屋には人がいます。人々は部屋を含んでおらず、部屋に属しています。

ゲスト数を取得するために必ずしも反復する必要はありません。実行中のカウント ($Hotel->total_guests) を保持し、変化に応じて変更することができます。

于 2010-04-11T02:45:38.673 に答える
4

クラス間の相互依存の問題は、厳密に言えば、インターフェイス (言語が C++ や Python の場合は抽象クラス)IRoomIPerson;を使用することで解決できます。疑似コードで

interface IPerson
    IRoom getRoom()
    // etc

interface IRoom
    iter<IPerson> iterPerson()
    // etc

これにより、インターフェイスのみが相互に依存するようになります。インターフェイスの実際の実装は、インターフェイスに依存するだけで済みます。

これにより、循環参照ループを回避したい場合(ガベージ コレクションの速度が低下するなど、CPython で問題になる可能性があります)、実装に関して十分な余裕が得られます-- 典型的な " 1 対多の関係」テーブルなど。そして、最初の単純なプロトタイプでは、選択した言語で最も単純なものを使用できます (おそらく単純で、悲しいことに必然的に循環し、参照 [[pointers, in C++]] をPersonaRoomとaRoomから a list<Person>)。

于 2010-04-11T03:03:23.530 に答える
1

大規模なシステムではそれは悪いことですが、私があなたのアプリケーションについて理解していることから、これら 3 つのクラスは一緒にしか使用されないため、それほど問題にはなりません。インスタンスではなく部屋への参照が含まれていることを示す方法で、個人のメンバー変数に名前を付けるようにしてください。

また、パフォーマンス上の理由でない限り (たとえば、膨大な数の部屋がある場合など)、ホテルにキャッシュするよりも、部屋を反復処理して人を収集するプロパティまたはゲッターを作成する方がおそらくクリーンです。

于 2010-04-11T02:48:01.810 に答える
0

相互依存は、それ自体は悪いことではありません。時々、データ使用量がそれを必要とします。

私はそれについて別の方法で考えています。一般に、相互依存関係の有無にかかわらず、関係が少ないコードを維持する方が簡単です。できるだけシンプルにしてください。あなたの状況での唯一の追加のトリッキーは、シーケンスの作成と削除中にチェックアンドエッグの問題が発生することがあります。簿記へのリンクが他にもあります。

この場合、ホテルに宿泊している人のリストが必要かどうかを尋ねる場合、2 つの答えがあると思います。これらの関係を提供するオブジェクト (メモリ内) を用意することから始めますが、データベース内の人とホテルの間に追加の結合テーブルは必要ありません。Hibernate を使用している場合、ホテル内の人々を要求すると、効率的な結合が自動的に生成されます (rooms.hotel_id でホテルに結合されます)。

于 2010-04-11T03:59:42.200 に答える