6

I want to know whats the Relationship between a common wall (that are located In an adjoining room ) and the rooms.
As i know the relationship between a room and its walls is Composition not Aggregation (am i right ?)

And according to the definition of Composition the contained object can't be shared between two containers, whereas in aggregation it is possible.

now i am confused that whats the best modeling approach to represent the relationship between a common wall and the rooms located next to it ?

It would be highly Appreciated if you could provide your advices with some code.

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

Approch1:

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

Approach2:

wall class ----- room class /Aggregation

Approch3:

we have a wall class and a Common wall class , Common wall class inherits from wall class

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

Approach4: I am a developer not a designer :) so this is my idea :

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
{
 //...
}

// in somewher :

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

Edit 1: I think this is a clear question but just for more clarification :

The point of the question is to find out whats the best pattern or approach to model a relationship for an object that is a component of two other objects in the same time.

and about my example : waht i mean by a "room" ?,surely i mean an enclosed square room with 4 walls and one door.but in this case one of these walls is a common wall and is shared between two adjacent rooms.

siamak
  • 669
  • 1
  • 10
  • 28
  • 1
    I guess I am confused. in this scenario, can a room only have one common wall? – Nathan Tregillus Jun 27 '12 at 23:55
  • 1
    Why does it really matter whether it's composition or aggregation? – Don Roby Jun 27 '12 at 23:57
  • 1
    The appropriate solution might depend on what you need to do with the data. Is there an RDBMS involved? Relate rooms and walls via a many-to-many relationship? Maybe you only track walls, and derive rooms based on distinct sets of walls. Common walls are walls that appear in more than one set? Room.Walls; Wall.Rooms; Track both all the parent rooms a wall belongs to and all that walls that make up each room. Do rooms have to be enclosed spaces? – ulty4life Jun 28 '12 at 00:06
  • 1
    This question may be better suited to http://programmers.stackexchange.com/ as this question isn't a specific 'solvable' problem, but more one of programming theory. – Russ Clarke Jun 28 '12 at 00:41
  • 1
    @Don it matters if you're worried about the lifecycle of your objects, quite a lot. Composition implies that all child objects may be disposed when the parent is disposed but aggregation is the opposite; think of the difference between your database code getting a connection from a pool rather then creating/destroying one each time your database class is instantiated. – Russ Clarke Jun 28 '12 at 00:44
  • It would be helpful to understand what you are trying to achieve. It looks like you are trying to understand real world environments using the language of programming. In the real world, a room does not have a **reference** to four walls as shown in approach 4. And my lounge room and dining room are both rooms but they don't have 4 walls each because they join without a common wall. – Michael Jun 28 '12 at 00:47
  • @Michael I believe he's referring to an old metaphor that conceptualises the wheres and whys of a good OO design. See: http://is.gd/x1T0vS – Russ Clarke Jun 28 '12 at 00:54
  • @NathanTregillus : if we could address this issue with only one common wall ,its possible to extend the solution for more of them, any way whats your suggestion for this specific case ? thanks – siamak Jun 28 '12 at 07:48
  • @ulty4life: you mentioned to an important point , we need a bidirectional relationship ,as the room knows about its walls , the walls or at least the common wall must know about its room(s), and about your question , if i understand it well , i must say yes , i mean two rooms that are conjoined to each other and and separated by a common wall.anyway based on this information whats your suggestion?thanks – siamak Jun 28 '12 at 08:18
  • @Michael : dear michael what do u mean by that ? as you know many of OO Concepts are inspired by the real world , could u please remember the first time that u heard about composition Agg and Asso , i am not sure but i know for many people it came with some real world example such as Car , Company ,University, department , Room , and ..., and in many books we can see them , so i think its a normal thing to think about them elaborately.and based on my knowledge one of the best way to implement composition is creating the part objects in the whole object do u know any better way ? – siamak Jun 28 '12 at 09:55
  • Hello @siamak - I didn't mean offence, just trying to understand what your question is about. OO is often explained in terms of real world things (Man and Woman both subclass Person), but you can come unstuck trying to explain real world things using OO. In the real world some people have only one arm, or no legs, or eleven fingers. Stack Overflow is meant for concrete programming questions, not discussions. Discussions tend to get closed pretty quickly by moderators. As mentioned by Russ, maybe you should post the question on [Programmers StackExchange](http://programmers.stackexchange.com/). – Michael Jun 28 '12 at 10:22
  • @Michael , Hi , U are right , but i think my question is clear , please look at this issue as a problem , how do u model such a thing ? is that ok? , i think Uml definitions of Relationships is poor , incomplete and imperfect , if not could u please guide me , i am interested in finding a good explanation for such a thing thanks – siamak Jun 28 '12 at 12:13
  • I think rooms should always be fully enclosed spaces. E.g. a square room would always have 4 walls. One of those walls however, could just have a really large "door" opening defined in the wall. That would cover the square room with 3 walls case, and allow you to model the empty wall as common between two rooms. – ulty4life Jun 28 '12 at 17:29
  • Can you tell us, once you have the rooms and walls modeled, what you need to do with them? What you need to do will help define what kind of data structure you need. Extreme flexibility likely has trade-offs of a more complex data structure and increased processing time. – ulty4life Jun 28 '12 at 17:38
  • @ulty4life :Yes , what u described about a room is exactly what i meant by a room and about your next command , The question is result of a discussion that i had with one of my colleague .just out of curiosity , its important for me to find out the answer . – siamak Jul 01 '12 at 13:22

6 Answers6

16

The answer to your question about the room and the wall is the answer to this question: "Can the wall exist without the room?"

I believe your scenario is using aggregation. Can the wall exist without the room? Sure it can. One could destroy the room by destroying three walls, but that remaining wall stands on its own. I think we're down to semantics now. This answer can change depending on how you view the walls in your scenario.

This link shows a concise way to think about it:

  1. A "owns" B = Composition : B has no meaning or purpose in the system without A
  2. A "uses" B = Aggregation : B exists independently (conceptually) from A

Same here:

Aggregation implies a relationship where the child can exist independently of the parent. Example: Class (parent) and Student (child). Delete the Class and the Students still exist.

Composition implies a relationship where the child cannot exist independent of the parent. Example: House (parent) and Room (child). Rooms don't exist separate to a House

From wikipedia:

Aggregation differs from ordinary composition in that it does not imply ownership. In composition, when the owning object is destroyed, so are the contained objects. In aggregation, this is not necessarily true. For example, a university owns various departments (e.g., chemistry), and each department has a number of professors. If the university closes, the departments will no longer exist, but the professors in those departments will continue to exist. Therefore, a University can be seen as a composition of departments, whereas departments have an aggregation of professors. In addition, a Professor could work in more than one department, but a department could not be part of more than one university.

Community
  • 1
  • 1
Bob Horn
  • 33,387
  • 34
  • 113
  • 219
  • I think I know the concepts that u mentioned , but based on This Concepts its hard to make a good decision for modeling such a problem,I think there is so many paradoxes here , if you destroy or delete the whole object (I mean the Room )the wall will no longer exist ,in fact it dosnt make sense so the relationship could be Composition from this point of view , on the other hand,in this example we can see that there is one Common instance at part section that is shared between two whole objects ,and as far as i know this is not permitted in the composition,so which option is correct to choose? – siamak Jun 28 '12 at 07:25
  • @siamak I believe your scenario is using aggregation. Can the wall exist without the room? Sure it can. One could destroy the room by destroying three walls, but that remaining wall stands on its own. I think we're down to semantics now. This answer can change depending on how *you* view the walls in *your* scenario. – Bob Horn Jun 28 '12 at 13:38
2

There is many to many relationship between Room and Wall. (one wall can be used in two rooms and one room can have many walls.

Instead of having a class like "CommonWall", I would suggest resolve this many to many with with Mapping object and two 1-Many relationships.

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;}
}
Anand
  • 4,523
  • 10
  • 47
  • 72
2

Bob Horn made a point here, when a wall can exist independently from the room it has to be an aggregation.

But remember that you model how you want to see / manipulate them, so you can also decide that you mainly care about your rooms and see the walls as a side effect of the room, then this is a composition.

Aggregation model

You build the wall and that defines your rooms, your room is the just the space between the walls.

Thinking that way, the room does not need to have 4 walls, it's just an arbitrary set of walls: an open room can have 3 walls and a L shapes closed room might have 6.

This is the representation an architect or a builder will adopt.

Composition model

You want to see a room as a space with walls, then what you really care about is the view of the wall from the inside side of the room. In that case you do not car if the other room has a common wall, when you destroy your room, the inside side of the wall disappears with it.

A shared wall becomes an aggregation of two room-walls.

This might be the correct representation if you are planning an exhibition and want define where paintings will be placed.

Model what best fit your needs

In the end you model a representation and thus a simplification. Similarly there is no correct or best answer when modeling your representation, you should model your representation after your needs.

If you want to buy a car you tend to define book as composed of its pages, when you dispose it you dispose every pages. If you want to print a book you tend to spare parts you as aggregating folios composed of pages, if a folio is misprinted you can take another from the stock to assemble to final book.

Julien Ch.
  • 1,231
  • 9
  • 16
1

It depends. There is always two sides to a wall. ;-)

In this sort of scenario I would use either use property injection or constructor injection, e.g.

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

And then use a creational pattern such as a builder pattern to construct the rooms using the shared walls.

Phil Carson
  • 884
  • 8
  • 18
1

How you deal with Rooms and Walls depends on the task at hand.

I'll illustrate this with two examples, and then I'll get back to giving my answer to the actual "point" of your question.

First Approach (Navigating a 1 story Building):

Objective: I want to tell a Robot to move from its current location to the Copy Room.

I determine the dimensions of the building, say 100 ft, by 100 ft. Choose an axis, and make a grid of points. The robot may start at location (50,50). Next, I create a Graph where each edge represents one step to North, East, South, or West from that node to the corresponding node. Nodes separated by a wall have infinite weight, i.e. can't be passed through.

The Graph is represented in an adjacency-list.

Now I define a Room to be a polygon and list its verticies. To test if the robot is in the room, it must be within the area defined by the room's polygon. In this case rooms can overlap, especially since in real life standing in the doorway could mean you are in either room.

My robot can now navigate the building, move furniture, and whatever else it wants to do.

Second Approach: (Object Oriented)

  • Building
    • Properties
      • Width, Length, Height, Geo-Spacial Coordinates, Age, etc.
    • OuterWalls
      • may be BrickWall, GlassWall, ConcreteWall, etc inherited from OuterWall
      • Properties: location, thickness, etc
      • Methods: DemolishWall(), PaintExterior( Color C ), etc.
    • InteriorWall
      • May be NorthSouthWall or EastWestWall.
      • Properties: hasDoorway, N/E color, S/W color, etc.
    • Room
      • Properties: Name, Location, Width, Length, etc.

Notice that in neither of these examples do the rooms directly refer to their walls.

Now to the actual point of your question. If two objects have a shared resource how should that be taken care of.

Parallel programming deals with shared resources in a variety of different ways.

  1. Give each object a reference to the shared resource, make sure to synchronize or otherwise deal with concurrent behavior on the shared resource.
  2. Make the shared resource available to each object as a global variable or through a singleton object, or a static resource in another class, or even a specific location in memory or file system.
  3. Pass the shared resource between the concurrent parts in a predefined order or at predefined times.

Imagine a hotel with a shared bathroom between each two rooms:

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.

But in the above example, how does the bathroom know which two HotelGuests have its key?

  1. create a database with the current guests and the keys they have, and the bathroom can query the database (or list).
  2. store references to A and B in the bathroom properties. (imagine a white-board in the bathroom listing its 'tenants').
Xantix
  • 3,321
  • 1
  • 14
  • 28
1

If this was anything close to real problem, I don't think I'd want to compose the Room from plain Walls. It's more likely I'd have collection of RoomComponents or IRoomComponents that would be injected using constructor injection or property injection. There is also possibility of using injection framework for composing the Room, so that the framework takes care of lifetime of the objects.

If for a second I'd imagine that the problem was really so simple that there were just Room and Walls, then I guess your approach #4 looks like the way to go. I am not sure what would be a proper name to that, as you have both Aggregation and Composition in there. Another way is to set the common wall as a property(property injection as mentioned above), instead of passing through constructor.

And finally if I go into fantasy world like some others in this thread, then I quickly come to realize all your walls should be common walls! Say someone build another three walls around one of the walls of an existing room -> bam you have a new a room, and a new common wall. What to do now? You would probably want to change the existing wall to a new CommonWall right? So it seems inevitable having walls as properties in this case, otherwise every time you decide to construct a neighbor room, you'd have to recreate all neighboring rooms.

m0s
  • 4,250
  • 9
  • 41
  • 64