tags:

views:

244

answers:

13

This question came to my mind quite a few times.

Let my explain my question through an example.

Say I've got two classes: 1- Grid. 2- Cell.

Now the location of the cell 'should' be stored in the grid class, not in the cell class itself. Say that the cell wanted to get its location through a method in the grid.

How can it do that? Keep in mind that the cell was created/initialised by the Grid class.

What good OO approach to solve this problem?

Thank you

+8  A: 

I don't think that's a good design. If the cell needs to know its location, it should hold it itself and provide methods for the grid to access it.

anon
The cell might not need to hold the location. The grid could provide the location on demand, calling some cell methods, which have location params.
m_pGladiator
@ m_pGladiator Of course - there are an infinite number of possible solutions. I prefer to go for the simplest first.
anon
Agreed that if the cell needs to know its location it should store it. But I don't think that's the real problem here. The real problem is that the cell shouldn't need to know its location at all.
John Dibling
@John I agree, but that was the question. It seems like the Cell is anon-object that could be got rid of. For example, if I were modelling a chess board, I'm not sure I would have a Square class, though obviously I would have a Piece class or classes.
anon
@Neil - Piece would be a way better model than the Cell, indeed :)
m_pGladiator
+2  A: 

Why does the cell need to know its location in the grid? Seems like the cell should be unaware of where it is located. If you still need this - The cell can hold a pointer to its enclosing grid, and it can ask it for the location (like this, inside the cell class: getGrid().getLocation(this))

duduamar
and how the grid will know cell's location? a search? that's a bad idea, and causes too many references being passed around, which is not exactly a good idea to do in C++
Ion Todirel
Normally the grid is the parent for the cells, so it know the locations.
m_pGladiator
You can turn the question around: why does the grid need to know the location of its cells? "All these cells make up the grid" could be more than enough.
MadKeithV
-1 Asking for the location is smelly in OOP (Tell, don't ask) and is probably indicative of a poor design decision.
Stiggler
A: 

Grid can search for a cell in itself with some function, that function can be optimized by having a cache or perhaps a dictionary/mapping of cells to n-tuples of integers.

Nick
+1  A: 

The best approach would be to ask the grid for a particular cell's location.

The other solution is to give the cell a pointer to the grid in it's constructor. When the cell is requested for it's location, it can return the location from a grid's function.

Indrek
A: 

I would consider storing the position in each cell object and the grid object should contain a collection of cells, the amount that were created. This way i'll solve some of the problems that i'll face.

Adrian Faciu
+1  A: 

If you want cell to know it's location, then just put it inside the cell. There's no point of keeping it out of the class, not that single cell can be used in different grids (since you already want to get it's location and that places such a restriction).

Alternatively, if cell method that needs to know location is called from grid, then I'd just pass location as parameters to that method.

In some very special cases you might store reference to a grid in a cell or pass it as parameter to it's methods but it just feels wrong, in introduces too much coupling.

vava
A: 

If it's the grid's responsibility then you have to let the cell know what grid it belongs to. Add this to the constructor of the cell.

The only question here for you to consider is really who's responsibility is it to know the location.

bitc
+1  A: 

That's easy, just make the constructor of the Cell take its location, suppose this is the constructor:

public:
    Cell(/*assume this is a generic type*/T value, int i, int j)
    {
    }

Why would you do that? Well first because after you create a cell its location it's pretty much fixed, unless you'll do specialized operations like 'insert'. I do not recommend calling methods on the Grid, or keeping a Grid instance locally.

Ion Todirel
Why do you assume the location is fixed? You might drag'n'drop the cell somewhere else (even on another grid!)
m_pGladiator
I agree with 'Ion', my view is that the location of the cell is fixed, but the content of the cell is not.So if you drag'n'drop something, you're handling the content of that cell not the cell it self.That's at least how I see it.
m4design
@m_pGladiator, that's why I said "unless you'll do inserts", when you drag and drop, in most cases that would be a insert and in some cases it will be an add, or it could be neither, as M4 says, and have as a result just a value change.
Ion Todirel
Yeah, true, but then the Cell is mutable - you modify its internal contents when moving around. I was thinking in a way like drag'n'drop actually "reparents" the same cell object in another grid, without any value change in the cell, except its location. But the cell does not know its location, because it is managed by the Grid itself.
m_pGladiator
+1  A: 

For me it does not seem necessary for the cell to know its location in the Grid. The important is that not the Cell gets its location from the Grid, but the Grid gives the location to the cell when needed! So the Grid calls a method of the Cell, to do this. Not the other way around.

The most logical will be that the Grid contains many cells, so it "owns" them (e.g. creates the cells, moves them around or whatever). Therefore, the Cell should not know anything about the Grid.

The cell itself contains some information. This information might need to be refreshed or something else, depending on the location in the grid. Then you could have a method in the Cell, called by the Grid to do this. That method might accept location parameters if needed, but the cell itself does not hold them as a members.

m_pGladiator
A: 

I guess what you're saying is that a cell's location in the grid is not intrinsic to its "Cell-ness" so to speak, that you want to have the concept of a Cell independent of a Grid, so the cell object should not have any grid-specific informaiton.

I'm not sure how valuable a distinction that is, but if you want it, there's a couple options:

  • Make Cell a base class, and derive GridCell from it. GridCell contains either a back-pointer to the containing Grid object or its location, as the other answers suggest.
  • Use something like the Decorator pattern to add the grid-specific information and interfaces to the Cell object at run-time.

Again, it smells like we're making this harder than it is -- I'm not sure it makes sense to have a Cell that's not part of a Grid, and this I don't see the harm in having Cell objects maintain their position in the grid. In fact, it strikes me has simpler to have the Grid object maintain a simple collection of Cell objects, each of which are responsible for knowing their location in the Grid.

JohnMcG
A: 

Factory Method Design Pattern

Define an interface for creating object, but the let your subclass decide which class to instantiate. The Factory Method defines an interface for creating objects, but lets subclasses decide which classes to instantiate.

Vinothbabu
+3  A: 

I'd look at it the following way:

  • The "Grid" is just a collection of "Cell"s
  • Each "Cell" has its location in the "Grid" as data members
  • Each "Cell" may contain a "Data" object that holds the actual user-contents of the "Cell"

This way, you can treat a "Cell" as a coordinate within the grid.

MadKeithV
That's exactly what I was thinking.
m4design
+1  A: 

As Neil suggests, if the cell needs to know its location it should store it.

That being said, I dont think the cell should need to know its location. The grid is in charge of managing the cells, including their location, telling them where to draw themselves, etc. The cells should be in charge of what cells contain -- eg, data, formatting information, etc.

So the cell should never need to know its location within the grid. It may need to do things like draw itself, but that should be done in terms of screen coordinates passed in by the grid. The grid should control which cells are painted & where. The cells should just do what they are told & where.

John Dibling
I actually designed my project to this criteria, but I was thinking that if the cell holds it's position, then it should provide the method that for showing the its position.The grid would know each cell's position, because it constructs itself of many cells.So if a grid is created of cell[5][5], then the cell[0][0] would know that it lies in (row=0, col=0) in the grid. The grid of course would know that too.To improve the design I made the position of the cell constant, so when a cell is constructed, the location would be fixed from the beginning.I think this isn't so horrible design.
m4design