Simple OOP-related question
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 t开发者_如何学JAVAhe 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
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.
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.
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))
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.
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.
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.
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.
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.
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.
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.
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.
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 deriveGridCell
from it.GridCell
contains either a back-pointer to the containingGrid
object or its location, as the other answers suggest. - Use something like the
Decorator
pattern to add the grid-specific information and interfaces to theCell
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
.
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.
精彩评论