6

隣接する部屋にある共有の壁と部屋の間の関係を知りたいです。
私が知っているように、部屋とその壁の関係はComposition not Aggregation(そうですか?)

And according to the definition of 構成 the contained object can't be shared between two containers, whereas in の集約 it is possible

今、私は、共通の壁とその隣にある部屋との関係を表現するための最良のモデリング アプローチは何かと混乱しています。

いくつかのコードでアドバイスを提供できれば、非常に高く評価されます。

|--------|--------|

アプローチ1:

(wall class ---- room class) /Composition

アプローチ2:

wall class ----- room class /Aggregation

アプローチ3:

壁クラスと共通壁クラスがあり、共通壁クラスは壁クラスから継承します

adjoining room class ---- (1) Common wall class /Aggregation
adjoining room class ---- (6) wall class / composition

アプローチ4: 私はデザイナーではなく開発者です:)これが私の考えです:

class Room 
{
  private wall _firstwall  ;
  private wall _secondtwall;
  private wall _thirdwall  ; 
  private wall _commonwall ;

public Room( CommonWall commonwall)
 {
 _firstwall=new Wall();
 _secondtwall=new Wall();
 _thirdwall=new Wall();
 _commonwall=commonwall;
 }

}

Class CommonWall:Wall
{
 //...
}

// どこかで :

 static void main()
{
  Wall _commonWall=new Wall();
  Room room1=new Room(_commonWall);
  Room room2=new Room(_commonWall);
  Room [] adjacentRoom =new Room[2]{room1,room2};
}

編集1: これは明確な質問だと思いますが、より明確にするためだけです:

質問のポイントは、同時に他の 2 つのオブジェクトのコンポーネントであるオブジェクトの関係をモデル化するための最良のパターンまたはアプローチを見つけることです

そして私の例について:「部屋」とはどういう意味ですか?確かに、4つの壁と1つのドアで囲まれた正方形の部屋を意味します.しかし、この場合、これらの壁の1つは共通の壁であり、隣接する2つの部屋で共有されています.

4

6 に答える 6

16

部屋と壁についてのあなたの質問への答えは、この質問への答えです:「壁は部屋なしで存在できますか?」

あなたのシナリオは集計を使用していると思います。部屋がなければ壁は存在できますか?確かにそれはできます。3 つの壁を破壊することで部屋を破壊できますが、残りの壁は自立します。私たちは今、セマンティクスに落ちていると思います。この答えは、シナリオで壁をどのように見るによって変わる可能性があります。

このリンクは、それについて考えるための簡潔な方法を示しています。

  1. A が B を「所有」 =構成: B は、A なしではシステム内で意味も目的もありません
  2. A が B を「使用」 =集約: B は A とは (概念的に) 独立して存在します。

ここも同じ:

集約とは、子が親から独立して存在できる関係を意味します。例: クラス (親) と生徒 (子)。クラスを削除しても、生徒はまだ存在します。

構成とは、子が親から独立して存在できない関係を意味します。例:家(親)と部屋(子)。ルームはハウスとは別に存在しません

ウィキペディアから:

集約は、所有権を意味しないという点で、通常の合成とは異なります。コンポジションでは、所有しているオブジェクトが破棄されると、含まれているオブジェクトも破棄されます。集計では、これは必ずしも当てはまりません。たとえば、大学にはさまざまな学部 (化学など) があり、各学部には多数の教授がいます。大学が閉鎖されれば、学科はなくなりますが、学科の教授は存続します。したがって、大学は学部の集まりと見なすことができますが、学部には教授の集合体があります。さらに、教授は複数の学部で働くことができますが、学部が複数の大学の一部になることはできません。

于 2012-06-28T00:33:03.640 に答える
2

Bob Hornはここで強調しました。壁が部屋から独立して存在できる場合、それは集合体でなければなりません。

ただし、それらをどのように表示/操作するかをモデル化することを忘れないでください。したがって、主に部屋を気にし、壁を部屋の副次的な効果として見ることもできます。これが構成です。

集計モデル

あなたは壁を作り、それがあなたの部屋を定義します。あなたの部屋は壁の間の空間です。

そのように考えると、部屋に 4 つの壁がある必要はなく、任意の壁のセットにすぎません。開いた部屋には 3 つの壁があり、L 字型の閉じた部屋には 6 つの壁がある場合があります。

これは、アーキテクトまたはビルダーが採用する表現です。

構成モデル

部屋を壁のある空間として見たいなら、本当に気にするのは部屋の内側から見た壁の眺めです。その場合、他の部屋に共通の壁がある場合は車に乗りません。自分の部屋を破壊すると、壁の内側が一緒に消えます。

共有壁は、2 つの部屋の壁の集合体になります。

展覧会を計画していて、絵画を配置する場所を定義したい場合は、これが正しい表現かもしれません。

ニーズに最適なものをモデル化

最後に、表現をモデル化し、単純化します。同様に、表現をモデル化するときに正解最良の答えはありません。必要に応じて表現をモデル化する必要があります。

車を購入したい場合、本をそのページで構成されていると定義する傾向があります。それを処分するときは、すべてのページを処分します。本を印刷したい場合は、ページで構成されたフォリオを集約してパーツをスペアする傾向があります。フォリオが誤って印刷された場合は、在庫から別のフォリオを取り出して最終的な本に組み立てることができます。

于 2012-07-05T21:12:28.227 に答える
2

Room と Wall の間には多対多の関係があります。(1つの壁で2部屋、1つの部屋で何枚も壁を作ることができます。

「CommonWall」のようなクラスを持つ代わりに、この多対多を Mapping オブジェクトと 2 つの 1-Many 関係で解決することをお勧めします。

public class Room 
{
public List<Wall> Walls{get;set;}

}

public class Wall
{
decimal length;
decimal width;
public List<Room> Rooms{get;set;}
}

public class RoomWallMapping
{
public int MappingID;
public Wall {get;set;}
public Room{get;set;}
}
于 2012-07-05T09:20:35.660 に答える
1

場合によります。壁には常に 2 つの側面があります。;-)

この種のシナリオでは、プロパティ注入またはコンストラクター注入のいずれかを使用します。

public class Room
{
    public List<Wall> Walls { get; set; }
    public Room ( IEnumerable<Wall> walls )
    {
        Walls = new List<Wall>(walls);
    }
}

そして、ビルダー パターンなどの創造的なパターンを使用して、共有壁を使用して部屋を構築します。

于 2012-07-02T22:26:03.543 に答える
1

部屋と壁をどのように扱うかは、目の前のタスクによって異なります。

これを 2 つの例で説明します。その後、質問の実際の「要点」に対する回答に戻ります。

最初のアプローチ (1 階建ての建物をナビゲートする):

目的: ロボットに現在の場所からコピー ルームに移動するよう伝えたい。

建物の寸法、たとえば 100 フィートを 100 フィート単位で決定します。軸を選択し、点のグリッドを作成します。ロボットは位置 (50,50) から開始できます。次に、各エッジがそのノードから対応するノードまでの北、東、南、または西への 1 つのステップを表すグラフを作成します。壁で区切られたノードは、無限の重みを持ちます。つまり、通過できません。

グラフは隣接リストで表されます。

次に、Room をポリゴンとして定義し、その頂点をリストします。ロボットが部屋にいるかどうかをテストするには、ロボットが部屋のポリゴンで定義された領域内にある必要があります。この場合、部屋が重なっている可能性があります。特に、実際に出入り口に立っていると、どちらかの部屋にいることを意味する可能性があるためです。

私のロボットは、建物をナビゲートしたり、家具を動かしたり、その他やりたいことが何でもできるようになりました。

2 番目のアプローチ: (オブジェクト指向)

  • 建物
    • プロパティ
      • 幅、長さ、高さ、地理空間座標、年齢など
    • 外壁
      • OuterWall から継承された BrickWall、GlassWall、ConcreteWall など
      • プロパティ: 位置、厚さなど
      • メソッド: DemolishWall()、PaintExterior( Color C ) など
    • 内壁
      • NorthSouthWall または EastWestWall の場合があります。
      • プロパティ: hasDoorway、N/E カラー、S/W カラーなど。
    • 部屋
      • プロパティ: 名前、場所、幅、長さなど

これらの例では、部屋が壁を直接参照していないことに注意してください。

さて、あなたの質問の実際のポイントに。2 つのオブジェクトが共有リソースを持っている場合、どのように処理する必要がありますか。

並列プログラミングは、さまざまな方法で共有リソースを扱います。

  1. 各オブジェクトに共有リソースへの参照を与え、必ず同期するか、共有リソースでの同時動作に対処してください。
  2. グローバル変数として、またはシングルトン オブジェクト、別のクラスの静的リソース、さらにはメモリまたはファイル システム内の特定の場所を介して、共有リソースを各オブジェクトで使用できるようにします。
  3. 事前定義された順序または事前定義された時間に、並行部分間で共有リソースを渡します。

2 つの部屋の間でバスルームが共有されているホテルを想像してみてください。

HotelGuest A = new HotelGuest( new BusinessMan() );
HotelGuest B = new HotelGuest( new Programmer() );

A.Room = 101;
A.Bathroom = 7;
A.BathroomKey = getBathroomKey(7);

B.Room = 102;
B.Bathroom = 7;
B.BathroomKey = getBathroomKey(7);

//Asynchronously
A.RunDoBusinessStuff();
B.RunProgrammerStuff();

//but each has to lock bathroom7 when they use it, or it could be embarrassing.

しかし、上記の例では、どの 2 つの HotelGuest がそのキーを持っているかをバスルームはどのようにして知るのでしょうか?

  1. 現在のゲストと彼らが持っているキーを使用してデータベースを作成すると、バスルームはデータベース (またはリスト) にクエリを実行できます。
  2. バスルームのプロパティに A と B への参照を保存します。(その「テナント」をリストするバスルームのホワイトボードを想像してみてください)。
于 2012-07-03T00:00:14.117 に答える
1

これが実際の問題に近いものである場合、単純な壁から部屋を構成したいとは思いません。コンストラクター注入またはプロパティ注入を使用して注入される RoomComponents または IRoomComponents のコレクションがある可能性が高くなります。フレームワークがオブジェクトの存続期間を処理するように、ルームを構成するためにインジェクション フレームワークを使用する可能性もあります。

少しの間、問題が非常に単純で部屋と壁しかないと想像した場合、あなたのアプローチ#4が進むべき道のように見えると思います。集約と構成の両方が含まれているため、適切な名前が何であるかはわかりません。別の方法は、コンストラクターを通過する代わりに、共通の壁をプロパティとして設定することです (上記のプロパティ注入)。

そして最後に、このスレッドの他の人たちと同じようにファンタジーの世界に足を踏み入れると、あなたの壁はすべて共通の壁であるべきだとすぐに気付きます! 誰かが既存の部屋の壁の 1 つの周りに別の 3 つの壁を構築するとします -> 新しい部屋と新しい共通の壁があります。今何をする?おそらく、既存の壁を新しい CommonWall に変更したいと思うでしょう。したがって、この場合、プロパティとして壁を持つことは避けられないように思われます。そうしないと、隣接する部屋を構築することを決定するたびに、隣接するすべての部屋を再作成する必要があります。

于 2012-07-09T06:39:05.147 に答える