Should the Card class handle it's own position?
No. As you said, a card is defined purely by its rank and suite. The 10 of Spades remains the 10 of Spades regardless of where it is. In fact I would argue cards have no relevant methods other than getting the rank and suit. (It's convenient to define equals
and hashCode
as methods, but if you have access to the rank and suit you can compare cards without access to their private fields. It's just simpler not to have to pass Comparators
or whatnot when sorting, etc. If you make cards enums, you get this for free.)
As a side note, there's two separate concepts of position here. There's the abstract logical position relevant to the game logic (e.g. the 10 of Spades is on top of the 4th stack from the left) and then there's the presentation position (e.g. the 4th stack from the left is drawn at screen coordinates 58, 160). The abstract position of the stacks belongs in the model; the presentation position in the view.
Wouldn't that mean that my model is not decoupled properly?
Yes, if you introduce the screen position into the Card class, you've introduced coupling from the model to the view. (Coupling in the other direction - from view to model - is normal.) For example, if you wanted to make the game look fancier by having 3D cards moved around a 3D table, you'd have to change the Card class to contain 3D points instead of 2D points. You don't just want to make it so you can change view implementations by swapping one class for another - you also want to isolate the model from being impacted by changes to the view's design.
If the View should handle the card's position, wouldn't that create excessive objects and references?
I don't see how moving the card's position from one layer of the program to another changes the amount of data you have to keep track of. Even if it did, it probably won't change the asymptotic time or space usage of the program. Even if it did, it's too early to worry about optimizing if you don't have clearly-defined performance goals and an implementation you can benchmark. It's doubtful a game with such little data to keep track of will have a performance issue unless you're doing something very, very wrong.